import { Service } from "root-ts" import Account = Type.Account.AccountService.Account import { MongodbService } from "root-ts"; import { RouteDecorator, RouteDecoratorFactory } from "root-ts"; import { AccountService } from "./accountService" import { Errors } from "../errors" export class RoleService extends Service { public readonly dependencies = ["MongodbService", "AccountService"] public readonly name = "RoleService" services: { AccountService: AccountService MongodbService: MongodbService } constructor(settings: { role: { root: string public: string user: string supports: string[] } }) { super({ role: { root: "", public: "public", user: "user", supports: [], collectionName: "role" } }, settings) } account: AccountService initialize() { this.account = this.services.AccountService } setAccountRole(option: { accountId: string role: string }, callback: Callback) { this.account.accountCollection.updateOne({ id: option.accountId }, { $set: { role: option.role } }, (err) => { callback(err, option.role) }) } getPublic() { return this.settings.role.public || "public" } getDefaultUserRole() { return this.settings.role.user || "user" } isRoot(account: Account) { return account.name == this.settings.role.root } withRole(name: string): RouteDecorator { let roles = this.settings.role.supports || [] roles = roles.slice() roles.push(this.settings.role.public, "root", this.settings.role.user) if (roles.indexOf(name) < 0) { throw new Errors.LogicError(`${name} doesn't support`) } return RouteDecoratorFactory.decorate((ctx, pass) => { if (!ctx.info || !ctx.info.account) { ctx.error(new Errors.Forbidden("Invalid role")) return } if (name == "root") { if (ctx.info.account.name == this.settings.role.root) { ctx.info.role = "root" pass() } else { ctx.error(new Errors.Forbidden("Not allowed")) } return } let accountId = ctx.info.account.id let role = ctx.info.account.role if (role === name) { ctx.info.role = name pass() return } else { ctx.error(new Errors.Forbidden(`Need to be role ${name}`)) return } }) } }