OSSecureFileWrapper/index.ts

125 lines
3.5 KiB
TypeScript
Raw Normal View History

2018-02-01 15:27:01 +00:00
import * as rsa from "node-rsa";
import fetch, { Response } from "node-fetch";
export interface File {
_id: string;
type: "binary" | "text";
name: string;
time: string;
preview: string;
version: string;
}
export interface History {
file: File;
history: File[];
}
export default class SecureFile {
private Server: string;
private Username: string;
private PrivateKey: string;
constructor(server: string, username: string, private_key: string) {
this.Server = server;
this.Username = username;
this.PrivateKey = private_key;
}
private async getCode() {
let code_res = await fetch(this.Server + "/code?username=" + this.Username);
//ToDo check status Codes
let code = (await code_res.json()).code;
let r = new rsa(this.PrivateKey, "pkcs1-pem");
return { code: code, signature: r.sign(code).toString("base64") };
}
private async makeRequest(endpoint: string, method: "POST" | "GET" | "PUT" | "DELETE", query: any, body: Buffer) {
let code = await this.getCode();
query.code = code.code;
query.signature = code.signature;
let query_str = "?";
let first = true;
for (let key in query) {
if (!first) query_str += "&";
query_str += encodeURIComponent(key) + "=" + encodeURIComponent(query[key]);
first = false;
}
return await fetch(this.Server + endpoint + query_str, { method: method, body: body });
}
async list(): Promise<File[]> {
let res = await this.makeRequest("/files", "GET", {}, undefined)
statusParser(res);
return await res.json();
}
async create(name: string, data: Buffer, type: "text" | "binary", preview?: Buffer): Promise<File> {
let res = await this.makeRequest("/files", "POST", { type: type, name: name, preview: preview }, data)
statusParser(res);
return res.json();
}
async get(id: string, version?: string): Promise<Buffer> {
let res: Response;
if (typeof version === "string") {
res = await this.makeRequest(`/files/${id}/history/${version}`, "GET", {}, undefined);
} else {
res = await this.makeRequest("/files/" + id, "GET", {}, undefined);
}
statusParser(res);
return res.buffer();
}
async update(id: string, data: Buffer, preview?: Buffer): Promise<File> {
let put: any = {};
if (preview) put.preview = preview;
let res = await this.makeRequest("/files/" + id, "PUT", put, data);
statusParser(res);
return res.json();
}
async delete(id: string): Promise<boolean> {
let res = await this.makeRequest("/files/" + id, "DELETE", {}, undefined);
statusParser(res);
return res.json();
}
async history(id: string): Promise<History> {
let res = await this.makeRequest(`/files/${id}/history`, "GET", {}, undefined);
statusParser(res);
return res.json();
}
}
export class Unauthorized extends Error {
constructor() {
super("Not authorized");
}
}
export class NotFound extends Error {
constructor() {
super("Not found");
}
}
export class BadRequest extends Error {
constructor() {
super("Bad request");
}
}
function statusParser(res: Response) {
if (res.status !== 200) {
switch (res.status) {
case 400:
throw new BadRequest();
case 404:
throw new NotFound();
case 403:
throw new Unauthorized();
default:
throw new Error(res.statusText);
}
}
}