Compare commits
4 commits
b7b6694407
...
9a1f4a2985
Author | SHA1 | Date | |
---|---|---|---|
9a1f4a2985 | |||
e17eb30aed | |||
668d8448da | |||
0b7de992c8 |
9 changed files with 188 additions and 30 deletions
|
@ -43,6 +43,9 @@ export class calendar {
|
||||||
@UpdateDateColumn()
|
@UpdateDateColumn()
|
||||||
updatedAt: Date;
|
updatedAt: Date;
|
||||||
|
|
||||||
|
@Column({ type: "varchar", nullable: true, default: null, unique: true })
|
||||||
|
webpageId: string;
|
||||||
|
|
||||||
@ManyToOne(() => calendarType, (t) => t.calendar, {
|
@ManyToOne(() => calendarType, (t) => t.calendar, {
|
||||||
nullable: false,
|
nullable: false,
|
||||||
onDelete: "RESTRICT",
|
onDelete: "RESTRICT",
|
||||||
|
|
|
@ -9,7 +9,7 @@ export class calendarType {
|
||||||
@Column({ type: "varchar", length: 255, unique: true })
|
@Column({ type: "varchar", length: 255, unique: true })
|
||||||
type: string;
|
type: string;
|
||||||
|
|
||||||
@Column({ type: "boolean" }) // none specified cal dav request
|
@Column({ type: "boolean", default: false }) // none specified cal dav request
|
||||||
nscdr: boolean;
|
nscdr: boolean;
|
||||||
|
|
||||||
@Column({ type: "varchar", length: 255 })
|
@Column({ type: "varchar", length: 255 })
|
||||||
|
@ -18,6 +18,9 @@ export class calendarType {
|
||||||
@Column({ type: "varchar", length: 255, nullable: true, default: null })
|
@Column({ type: "varchar", length: 255, nullable: true, default: null })
|
||||||
passphrase: string | null;
|
passphrase: string | null;
|
||||||
|
|
||||||
|
@Column({ type: "boolean", default: false })
|
||||||
|
sendToWebpage: boolean;
|
||||||
|
|
||||||
@OneToMany(() => calendar, (c) => c.type, {
|
@OneToMany(() => calendar, (c) => c.type, {
|
||||||
nullable: false,
|
nullable: false,
|
||||||
onDelete: "RESTRICT",
|
onDelete: "RESTRICT",
|
||||||
|
|
|
@ -22,6 +22,9 @@ export class user {
|
||||||
@Column({ type: "varchar", length: 255 })
|
@Column({ type: "varchar", length: 255 })
|
||||||
secret: string;
|
secret: string;
|
||||||
|
|
||||||
|
@Column({ type: "boolean", default: false })
|
||||||
|
static: boolean;
|
||||||
|
|
||||||
@Column({ type: "boolean", default: false })
|
@Column({ type: "boolean", default: false })
|
||||||
isOwner: boolean;
|
isOwner: boolean;
|
||||||
|
|
||||||
|
|
|
@ -21,8 +21,7 @@ export type BackupSectionRefered = {
|
||||||
};
|
};
|
||||||
|
|
||||||
export type BackupFileContent = { [key in BackupSection]?: BackupFileContentSection } & {
|
export type BackupFileContent = { [key in BackupSection]?: BackupFileContentSection } & {
|
||||||
collectIds: boolean;
|
backup_file_details: { collectIds: boolean; createdAt: Date; version: 1 };
|
||||||
version: 1;
|
|
||||||
};
|
};
|
||||||
export type BackupFileContentSection = Array<any> | { [key: string]: Array<any> };
|
export type BackupFileContentSection = Array<any> | { [key: string]: Array<any> };
|
||||||
|
|
||||||
|
@ -90,7 +89,7 @@ export default abstract class BackupHelper {
|
||||||
filename = new Date().toISOString().split("T")[0];
|
filename = new Date().toISOString().split("T")[0];
|
||||||
}
|
}
|
||||||
|
|
||||||
let json: BackupFileContent = { collectIds, version: 1 };
|
let json: BackupFileContent = { backup_file_details: { collectIds, createdAt: new Date(), version: 1 } };
|
||||||
for (const section of this.backupSection) {
|
for (const section of this.backupSection) {
|
||||||
json[section.type] = await this.getSectionData(section.type, collectIds);
|
json[section.type] = await this.getSectionData(section.type, collectIds);
|
||||||
}
|
}
|
||||||
|
@ -131,7 +130,7 @@ export default abstract class BackupHelper {
|
||||||
for (const section of sections
|
for (const section of sections
|
||||||
.filter((s) => Object.keys(backup).includes(s.type))
|
.filter((s) => Object.keys(backup).includes(s.type))
|
||||||
.sort((a, b) => a.orderOnInsert - b.orderOnInsert)) {
|
.sort((a, b) => a.orderOnInsert - b.orderOnInsert)) {
|
||||||
await this.setSectionData(section.type, backup[section.type], backup.collectIds ?? false);
|
await this.setSectionData(section.type, backup[section.type], backup.backup_file_details.collectIds ?? false);
|
||||||
}
|
}
|
||||||
|
|
||||||
this.transactionManager = undefined;
|
this.transactionManager = undefined;
|
||||||
|
|
|
@ -32,6 +32,19 @@ export default class PermissionHelper {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static canSome(
|
||||||
|
permissions: PermissionObject,
|
||||||
|
checks: Array<{
|
||||||
|
requiredPermissions: PermissionType | "admin";
|
||||||
|
section: PermissionSection;
|
||||||
|
module?: PermissionModule;
|
||||||
|
}>
|
||||||
|
) {
|
||||||
|
checks.reduce<boolean>((prev, curr) => {
|
||||||
|
return prev || this.can(permissions, curr.requiredPermissions, curr.section, curr.module);
|
||||||
|
}, false);
|
||||||
|
}
|
||||||
|
|
||||||
static canSection(
|
static canSection(
|
||||||
permissions: PermissionObject,
|
permissions: PermissionObject,
|
||||||
type: PermissionType | "admin",
|
type: PermissionType | "admin",
|
||||||
|
@ -48,6 +61,18 @@ export default class PermissionHelper {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static canSomeSection(
|
||||||
|
permissions: PermissionObject,
|
||||||
|
checks: Array<{
|
||||||
|
requiredPermissions: PermissionType | "admin";
|
||||||
|
section: PermissionSection;
|
||||||
|
}>
|
||||||
|
): boolean {
|
||||||
|
return checks.reduce<boolean>((prev, curr) => {
|
||||||
|
return prev || this.can(permissions, curr.requiredPermissions, curr.section);
|
||||||
|
}, false);
|
||||||
|
}
|
||||||
|
|
||||||
static passCheckMiddleware(
|
static passCheckMiddleware(
|
||||||
requiredPermissions: PermissionType | "admin",
|
requiredPermissions: PermissionType | "admin",
|
||||||
section: PermissionSection,
|
section: PermissionSection,
|
||||||
|
@ -60,11 +85,29 @@ export default class PermissionHelper {
|
||||||
if (isOwner || this.can(permissions, requiredPermissions, section, module)) {
|
if (isOwner || this.can(permissions, requiredPermissions, section, module)) {
|
||||||
next();
|
next();
|
||||||
} else {
|
} else {
|
||||||
throw new ForbiddenRequestException(
|
throw new ForbiddenRequestException(`missing permission for ${section}.${module}.${requiredPermissions}`);
|
||||||
`missing permission for ${section}.${module}.${
|
}
|
||||||
Array.isArray(requiredPermissions) ? requiredPermissions.join("|") : requiredPermissions
|
};
|
||||||
}`
|
}
|
||||||
);
|
|
||||||
|
static passCheckSomeMiddleware(
|
||||||
|
checks: Array<{
|
||||||
|
requiredPermissions: PermissionType | "admin";
|
||||||
|
section: PermissionSection;
|
||||||
|
module?: PermissionModule;
|
||||||
|
}>
|
||||||
|
): (req: Request, res: Response, next: Function) => void {
|
||||||
|
return (req: Request, res: Response, next: Function) => {
|
||||||
|
const permissions = req.permissions;
|
||||||
|
const isOwner = req.isOwner;
|
||||||
|
|
||||||
|
if (isOwner || this.canSome(permissions, checks)) {
|
||||||
|
next();
|
||||||
|
} else {
|
||||||
|
let permissionsToPass = checks.reduce<string>((prev, curr) => {
|
||||||
|
return prev + (prev != " or " ? "" : "") + `${curr.section}.${curr.module}.${curr.requiredPermissions}`;
|
||||||
|
}, "");
|
||||||
|
throw new ForbiddenRequestException(`missing permission for ${permissionsToPass}`);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
@ -80,11 +123,25 @@ export default class PermissionHelper {
|
||||||
if (isOwner || this.canSection(permissions, requiredPermissions, section)) {
|
if (isOwner || this.canSection(permissions, requiredPermissions, section)) {
|
||||||
next();
|
next();
|
||||||
} else {
|
} else {
|
||||||
throw new ForbiddenRequestException(
|
throw new ForbiddenRequestException(`missing permission for ${section}.${module}.${requiredPermissions}`);
|
||||||
`missing permission for ${section}.${module}.${
|
}
|
||||||
Array.isArray(requiredPermissions) ? requiredPermissions.join("|") : requiredPermissions
|
};
|
||||||
}`
|
}
|
||||||
);
|
|
||||||
|
static sectionPassCheckSomeMiddleware(
|
||||||
|
checks: Array<{ requiredPermissions: PermissionType | "admin"; section: PermissionSection }>
|
||||||
|
): (req: Request, res: Response, next: Function) => void {
|
||||||
|
return (req: Request, res: Response, next: Function) => {
|
||||||
|
const permissions = req.permissions;
|
||||||
|
const isOwner = req.isOwner;
|
||||||
|
|
||||||
|
if (isOwner || this.canSomeSection(permissions, checks)) {
|
||||||
|
next();
|
||||||
|
} else {
|
||||||
|
let permissionsToPass = checks.reduce<string>((prev, curr) => {
|
||||||
|
return prev + (prev != " or " ? "" : "") + `${curr.section}.${curr.requiredPermissions}`;
|
||||||
|
}, "");
|
||||||
|
throw new ForbiddenRequestException(`missing permission for ${permissionsToPass}`);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
|
@ -59,6 +59,7 @@ export const user_table = new Table({
|
||||||
{ name: "firstname", type: getTypeByORM("varchar"), length: "255", isNullable: false },
|
{ name: "firstname", type: getTypeByORM("varchar"), length: "255", isNullable: false },
|
||||||
{ name: "lastname", type: getTypeByORM("varchar"), length: "255", isNullable: false },
|
{ name: "lastname", type: getTypeByORM("varchar"), length: "255", isNullable: false },
|
||||||
{ name: "secret", type: getTypeByORM("varchar"), length: "255", isNullable: false },
|
{ name: "secret", type: getTypeByORM("varchar"), length: "255", isNullable: false },
|
||||||
|
{ name: "static", type: getTypeByORM("boolean"), isNullable: false, default: false },
|
||||||
{ name: "isOwner", type: getTypeByORM("boolean"), isNullable: false, default: false },
|
{ name: "isOwner", type: getTypeByORM("boolean"), isNullable: false, default: false },
|
||||||
],
|
],
|
||||||
});
|
});
|
||||||
|
|
|
@ -6,9 +6,10 @@ export const calendar_type_table = new Table({
|
||||||
columns: [
|
columns: [
|
||||||
{ name: "id", type: getTypeByORM("int"), isPrimary: true, isGenerated: true, generationStrategy: "increment" },
|
{ name: "id", type: getTypeByORM("int"), isPrimary: true, isGenerated: true, generationStrategy: "increment" },
|
||||||
{ name: "type", type: getTypeByORM("varchar"), length: "255", isUnique: true, isNullable: false },
|
{ name: "type", type: getTypeByORM("varchar"), length: "255", isUnique: true, isNullable: false },
|
||||||
{ name: "nscdr", type: getTypeByORM("boolean"), isNullable: false },
|
{ name: "nscdr", type: getTypeByORM("boolean"), isNullable: false, default: false },
|
||||||
{ name: "color", type: getTypeByORM("varchar"), length: "255", isNullable: false },
|
{ name: "color", type: getTypeByORM("varchar"), length: "255", isNullable: false },
|
||||||
{ name: "passphrase", type: getTypeByORM("varchar"), length: "255", isNullable: true },
|
{ name: "passphrase", type: getTypeByORM("varchar"), length: "255", isNullable: true },
|
||||||
|
{ name: "sendToWebpage", type: getTypeByORM("boolean"), isNullable: false, default: false },
|
||||||
],
|
],
|
||||||
});
|
});
|
||||||
|
|
||||||
|
@ -45,6 +46,14 @@ export const calendar_table = new Table({
|
||||||
default: "CURRENT_TIMESTAMP(6)",
|
default: "CURRENT_TIMESTAMP(6)",
|
||||||
onUpdate: "CURRENT_TIMESTAMP(6)",
|
onUpdate: "CURRENT_TIMESTAMP(6)",
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
name: "webpageId",
|
||||||
|
type: getTypeByORM("varchar"),
|
||||||
|
length: "255",
|
||||||
|
isNullable: true,
|
||||||
|
default: null,
|
||||||
|
isUnique: true,
|
||||||
|
},
|
||||||
{ name: "typeId", type: getTypeByORM("int"), isNullable: false },
|
{ name: "typeId", type: getTypeByORM("int"), isNullable: false },
|
||||||
],
|
],
|
||||||
foreignKeys: [
|
foreignKeys: [
|
||||||
|
|
|
@ -27,42 +27,120 @@ import preventWebapiAccess from "../../middleware/preventWebApiAccess";
|
||||||
|
|
||||||
var router = express.Router({ mergeParams: true });
|
var router = express.Router({ mergeParams: true });
|
||||||
|
|
||||||
router.use("/award", PermissionHelper.passCheckMiddleware("read", "settings", "award"), award);
|
router.use(
|
||||||
|
"/award",
|
||||||
|
PermissionHelper.passCheckSomeMiddleware([
|
||||||
|
{ requiredPermissions: "read", section: "settings", module: "award" },
|
||||||
|
{ requiredPermissions: "read", section: "club", module: "member" },
|
||||||
|
]),
|
||||||
|
award
|
||||||
|
);
|
||||||
router.use(
|
router.use(
|
||||||
"/communicationtype",
|
"/communicationtype",
|
||||||
PermissionHelper.passCheckMiddleware("read", "settings", "communication_type"),
|
PermissionHelper.passCheckSomeMiddleware([
|
||||||
|
{ requiredPermissions: "read", section: "settings", module: "communication_type" },
|
||||||
|
{ requiredPermissions: "read", section: "club", module: "member" },
|
||||||
|
]),
|
||||||
communicationType
|
communicationType
|
||||||
);
|
);
|
||||||
router.use(
|
router.use(
|
||||||
"/executiveposition",
|
"/executiveposition",
|
||||||
PermissionHelper.passCheckMiddleware("read", "settings", "executive_position"),
|
PermissionHelper.passCheckSomeMiddleware([
|
||||||
|
{ requiredPermissions: "read", section: "settings", module: "executive_position" },
|
||||||
|
{ requiredPermissions: "read", section: "club", module: "member" },
|
||||||
|
]),
|
||||||
executivePosition
|
executivePosition
|
||||||
);
|
);
|
||||||
router.use(
|
router.use(
|
||||||
"/membershipstatus",
|
"/membershipstatus",
|
||||||
PermissionHelper.passCheckMiddleware("read", "settings", "membership_status"),
|
PermissionHelper.passCheckSomeMiddleware([
|
||||||
|
{ requiredPermissions: "read", section: "settings", module: "membership_status" },
|
||||||
|
{ requiredPermissions: "read", section: "club", module: "member" },
|
||||||
|
]),
|
||||||
membershipStatus
|
membershipStatus
|
||||||
);
|
);
|
||||||
router.use("/qualification", PermissionHelper.passCheckMiddleware("read", "settings", "qualification"), qualification);
|
router.use(
|
||||||
router.use("/salutation", PermissionHelper.passCheckMiddleware("read", "settings", "salutation"), salutation);
|
"/qualification",
|
||||||
router.use("/calendartype", PermissionHelper.passCheckMiddleware("read", "settings", "calendar_type"), calendarType);
|
PermissionHelper.passCheckSomeMiddleware([
|
||||||
|
{ requiredPermissions: "read", section: "settings", module: "qualification" },
|
||||||
|
{ requiredPermissions: "read", section: "club", module: "member" },
|
||||||
|
]),
|
||||||
|
qualification
|
||||||
|
);
|
||||||
|
router.use(
|
||||||
|
"/salutation",
|
||||||
|
PermissionHelper.passCheckSomeMiddleware([
|
||||||
|
{ requiredPermissions: "read", section: "settings", module: "salutation" },
|
||||||
|
{ requiredPermissions: "read", section: "club", module: "member" },
|
||||||
|
]),
|
||||||
|
salutation
|
||||||
|
);
|
||||||
|
router.use(
|
||||||
|
"/calendartype",
|
||||||
|
PermissionHelper.passCheckSomeMiddleware([
|
||||||
|
{ requiredPermissions: "read", section: "settings", module: "calendar_type" },
|
||||||
|
{ requiredPermissions: "read", section: "club", module: "calendar" },
|
||||||
|
]),
|
||||||
|
calendarType
|
||||||
|
);
|
||||||
router.use("/querystore", PermissionHelper.passCheckMiddleware("read", "settings", "query_store"), queryStore);
|
router.use("/querystore", PermissionHelper.passCheckMiddleware("read", "settings", "query_store"), queryStore);
|
||||||
router.use("/template", PermissionHelper.passCheckMiddleware("read", "settings", "template"), template);
|
router.use("/template", PermissionHelper.passCheckMiddleware("read", "settings", "template"), template);
|
||||||
router.use("/templateusage", PermissionHelper.passCheckMiddleware("read", "settings", "template_usage"), templateUsage);
|
router.use(
|
||||||
|
"/templateusage",
|
||||||
|
PermissionHelper.passCheckSomeMiddleware([
|
||||||
|
{ requiredPermissions: "read", section: "settings", module: "template_usage" },
|
||||||
|
{ requiredPermissions: "read", section: "settings", module: "template" },
|
||||||
|
]),
|
||||||
|
templateUsage
|
||||||
|
);
|
||||||
router.use(
|
router.use(
|
||||||
"/newsletterconfig",
|
"/newsletterconfig",
|
||||||
PermissionHelper.passCheckMiddleware("read", "settings", "newsletter_config"),
|
PermissionHelper.passCheckSomeMiddleware([
|
||||||
|
{ requiredPermissions: "read", section: "settings", module: "newsletter_config" },
|
||||||
|
{ requiredPermissions: "read", section: "settings", module: "communication_type" },
|
||||||
|
]),
|
||||||
newsletterConfig
|
newsletterConfig
|
||||||
);
|
);
|
||||||
|
|
||||||
router.use("/member", PermissionHelper.passCheckMiddleware("read", "club", "member"), member);
|
router.use("/member", PermissionHelper.passCheckMiddleware("read", "club", "member"), member);
|
||||||
router.use("/protocol", PermissionHelper.passCheckMiddleware("read", "club", "protocol"), protocol);
|
router.use(
|
||||||
|
"/protocol",
|
||||||
|
PermissionHelper.passCheckSomeMiddleware([
|
||||||
|
{ requiredPermissions: "read", section: "club", module: "protocol" },
|
||||||
|
{ requiredPermissions: "read", section: "club", module: "member" },
|
||||||
|
]),
|
||||||
|
protocol
|
||||||
|
);
|
||||||
router.use("/calendar", PermissionHelper.passCheckMiddleware("read", "club", "calendar"), calendar);
|
router.use("/calendar", PermissionHelper.passCheckMiddleware("read", "club", "calendar"), calendar);
|
||||||
router.use("/querybuilder", PermissionHelper.passCheckMiddleware("read", "club", "query"), queryBuilder);
|
router.use(
|
||||||
router.use("/newsletter", PermissionHelper.passCheckMiddleware("read", "club", "newsletter"), newsletter);
|
"/querybuilder",
|
||||||
|
PermissionHelper.passCheckSomeMiddleware([
|
||||||
|
{ requiredPermissions: "read", section: "club", module: "query" },
|
||||||
|
{ requiredPermissions: "read", section: "settings", module: "query_store" },
|
||||||
|
]),
|
||||||
|
queryBuilder
|
||||||
|
);
|
||||||
|
router.use(
|
||||||
|
"/newsletter",
|
||||||
|
PermissionHelper.passCheckSomeMiddleware([
|
||||||
|
{ requiredPermissions: "read", section: "club", module: "newsletter" },
|
||||||
|
{ requiredPermissions: "read", section: "club", module: "member" },
|
||||||
|
{ requiredPermissions: "read", section: "club", module: "calendar" },
|
||||||
|
{ requiredPermissions: "read", section: "club", module: "query" },
|
||||||
|
{ requiredPermissions: "read", section: "settings", module: "query_store" },
|
||||||
|
]),
|
||||||
|
newsletter
|
||||||
|
);
|
||||||
|
|
||||||
router.use("/role", PermissionHelper.passCheckMiddleware("read", "user", "role"), role);
|
router.use("/role", PermissionHelper.passCheckMiddleware("read", "user", "role"), role);
|
||||||
router.use("/user", PermissionHelper.passCheckMiddleware("read", "user", "user"), user);
|
router.use(
|
||||||
|
"/user",
|
||||||
|
PermissionHelper.passCheckSomeMiddleware([
|
||||||
|
{ requiredPermissions: "read", section: "user", module: "user" },
|
||||||
|
{ requiredPermissions: "read", section: "user", module: "role" },
|
||||||
|
]),
|
||||||
|
user
|
||||||
|
);
|
||||||
router.use("/invite", PermissionHelper.passCheckMiddleware("read", "user", "user"), invite);
|
router.use("/invite", PermissionHelper.passCheckMiddleware("read", "user", "user"), invite);
|
||||||
router.use("/webapi", preventWebapiAccess, PermissionHelper.passCheckMiddleware("read", "user", "webapi"), api);
|
router.use("/webapi", preventWebapiAccess, PermissionHelper.passCheckMiddleware("read", "user", "webapi"), api);
|
||||||
|
|
||||||
|
|
|
@ -14,7 +14,12 @@ export default abstract class NewsletterRecipientsService {
|
||||||
.getRepository(newsletterRecipients)
|
.getRepository(newsletterRecipients)
|
||||||
.createQueryBuilder("newsletterRecipients")
|
.createQueryBuilder("newsletterRecipients")
|
||||||
.leftJoinAndSelect("newsletterRecipients.member", "member")
|
.leftJoinAndSelect("newsletterRecipients.member", "member")
|
||||||
.leftJoinAndSelect("member.sendNewsletter", "sendNewsletter")
|
.leftJoinAndMapOne(
|
||||||
|
"member.sendNewsletter",
|
||||||
|
"member.communications",
|
||||||
|
"sendNewsletter",
|
||||||
|
"sendNewsletter.isSendNewsletter = 1"
|
||||||
|
)
|
||||||
.leftJoinAndSelect("sendNewsletter.type", "communicationtype")
|
.leftJoinAndSelect("sendNewsletter.type", "communicationtype")
|
||||||
.leftJoinAndSelect("newsletterRecipients.newsletter", "newsletter")
|
.leftJoinAndSelect("newsletterRecipients.newsletter", "newsletter")
|
||||||
.where("newsletterRecipients.newsletterId = :id", { id: newsletterId })
|
.where("newsletterRecipients.newsletterId = :id", { id: newsletterId })
|
||||||
|
|
Loading…
Add table
Reference in a new issue