This repository has been archived on 2021-06-02. You can view files and clone it, but cannot push or open issues or pull requests.
RealtimeDB-OLD/src/database/rules.ts

111 lines
2.5 KiB
TypeScript

import Session from "./session";
import Logging from "@hibas123/nodelogging";
interface IRule<T> {
".write"?: T
".read"?: T
}
type IRuleConfig<T> = {
[segment: string]: IRuleConfig<T>;
} | IRule<T>;
type IRuleRaw = IRuleConfig<string>;
type IRuleParsed = IRuleConfig<boolean>;
const resolve = (value: any) => {
if (value === true) {
return true;
} else if (typeof value === "string") {
}
return undefined;
}
export class Rules {
rules: IRuleParsed;
constructor(private config: string) {
let parsed: IRuleRaw = JSON.parse(config);
const analyze = (raw: IRuleRaw) => {
let r: IRuleParsed = {};
if (raw[".read"]) {
let res = resolve(raw[".read"]);
if (res) {
r[".read"] = res;
}
delete raw[".read"];
}
if (raw[".write"]) {
let res = resolve(raw[".write"]);
if (res) {
r[".write"] = res;
}
delete raw[".write"];
}
for (let segment in raw) {
if (segment.startsWith("."))
continue;
r[segment] = analyze(raw[segment]);
}
return r;
}
this.rules = analyze(parsed);
}
hasPermission(path: string[], session: Session): { read: boolean, write: boolean } {
let read = this.rules[".read"] || false;
let write = this.rules[".write"] || false;
let rules = this.rules;
for (let segment of path) {
if (segment.startsWith("$") || segment.startsWith(".")) {
read = false;
write = false;
Logging.log("Invalid query path (started with '$' or '.'):", path);
break;
}
let k = Object.keys(rules)
.filter(e => e.startsWith("$"))
.find(e => {
switch (e) {
case "$uid":
if (segment === session.uid)
return true;
break;
}
return false;
})
rules = (k ? rules[k] : undefined) || rules[segment] || rules["*"];
if (rules) {
if (rules[".read"]) {
read = rules[".read"]
}
if (rules[".write"]) {
read = rules[".write"]
}
} else {
break;
}
}
return {
read: read as boolean,
write: write as boolean
}
}
toJSON() {
return this.config;
}
}