diff --git a/.gitignore b/.gitignore
index 3429ee7..18c3786 100644
--- a/.gitignore
+++ b/.gitignore
@@ -1,4 +1,3 @@
node_modules/
yarn.lock
-*.js
private.pem
diff --git a/entry.js b/entry.js
new file mode 100644
index 0000000..e69de29
diff --git a/index.d.ts b/index.d.ts
new file mode 100644
index 0000000..d158cdb
--- /dev/null
+++ b/index.d.ts
@@ -0,0 +1,36 @@
+///
+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;
+ private Username;
+ private PrivateKey;
+ constructor(server: string, username: string, private_key: string);
+ private getCode();
+ private makeRequest(endpoint, method, query, body);
+ list(): Promise;
+ create(name: string, data: Buffer, type: "text" | "binary", preview?: Buffer): Promise;
+ get(id: string, version?: string): Promise;
+ update(id: string, data: Buffer, preview?: Buffer): Promise;
+ delete(id: string): Promise;
+ history(id: string): Promise;
+}
+export declare class Unauthorized extends Error {
+ constructor();
+}
+export declare class NotFound extends Error {
+ constructor();
+}
+export declare class BadRequest extends Error {
+ constructor();
+}
diff --git a/index.js b/index.js
new file mode 100644
index 0000000..1dc012a
--- /dev/null
+++ b/index.js
@@ -0,0 +1,104 @@
+"use strict";
+Object.defineProperty(exports, "__esModule", { value: true });
+const rsa = require("node-rsa");
+const node_fetch_1 = require("node-fetch");
+class SecureFile {
+ constructor(server, username, private_key) {
+ this.Server = server;
+ this.Username = username;
+ this.PrivateKey = private_key;
+ }
+ async getCode() {
+ let code_res = await node_fetch_1.default(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") };
+ }
+ async makeRequest(endpoint, method, query, body) {
+ 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 node_fetch_1.default(this.Server + endpoint + query_str, { method: method, body: body });
+ }
+ async list() {
+ let res = await this.makeRequest("/files", "GET", {}, undefined);
+ statusParser(res);
+ return await res.json();
+ }
+ async create(name, data, type, preview) {
+ let res = await this.makeRequest("/files", "POST", { type: type, name: name, preview: preview }, data);
+ statusParser(res);
+ return res.json();
+ }
+ async get(id, version) {
+ let res;
+ 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, data, preview) {
+ let put = {};
+ if (preview)
+ put.preview = preview;
+ let res = await this.makeRequest("/files/" + id, "PUT", put, data);
+ statusParser(res);
+ return res.json();
+ }
+ async delete(id) {
+ let res = await this.makeRequest("/files/" + id, "DELETE", {}, undefined);
+ statusParser(res);
+ return res.json();
+ }
+ async history(id) {
+ let res = await this.makeRequest(`/files/${id}/history`, "GET", {}, undefined);
+ statusParser(res);
+ return res.json();
+ }
+}
+exports.default = SecureFile;
+class Unauthorized extends Error {
+ constructor() {
+ super("Not authorized");
+ }
+}
+exports.Unauthorized = Unauthorized;
+class NotFound extends Error {
+ constructor() {
+ super("Not found");
+ }
+}
+exports.NotFound = NotFound;
+class BadRequest extends Error {
+ constructor() {
+ super("Bad request");
+ }
+}
+exports.BadRequest = BadRequest;
+function statusParser(res) {
+ 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);
+ }
+ }
+}
diff --git a/package.json b/package.json
index 285c18d..3b3d165 100644
--- a/package.json
+++ b/package.json
@@ -1,9 +1,10 @@
{
- "name": "SecureFileWrapper",
- "version": "1.0.0",
+ "name": "secure-file-wrapper",
+ "version": "1.0.1",
"main": "index.js",
"author": "Fabian Stamm ",
"license": "MIT",
+ "types": "index.d.ts",
"scripts": {
"build": "tsc",
"test": "nodeunit test.js"
diff --git a/test.d.ts b/test.d.ts
new file mode 100644
index 0000000..e69de29
diff --git a/test.js b/test.js
new file mode 100644
index 0000000..0dae075
--- /dev/null
+++ b/test.js
@@ -0,0 +1,81 @@
+"use strict";
+Object.defineProperty(exports, "__esModule", { value: true });
+const index_1 = require("./index");
+const fs_1 = require("fs");
+const buffer_1 = require("buffer");
+let sf;
+const testname = "ouiavgbsop687463743";
+const testdata = new buffer_1.Buffer("Ich bin ein Test");
+const newTestData = new buffer_1.Buffer("neue test daten");
+const testprev = new buffer_1.Buffer("Ich bin...");
+let testid;
+let testver;
+let testver2;
+module.exports = {
+ setUp: function (finished) {
+ let pk = fs_1.readFileSync("./private.pem");
+ sf = new index_1.default("http://localhost:3005", "test", pk.toString("utf8"));
+ finished();
+ },
+ create: async function (test) {
+ test.expect(2);
+ let res = await sf.create(testname, testdata, "text", testprev);
+ test.ok(res);
+ test.ok(res._id);
+ testid = res._id;
+ testver = res.version;
+ test.done();
+ },
+ get: async function (test) {
+ test.expect(2);
+ let res = await sf.get(testid);
+ test.ok(res);
+ test.equal(res.toString(), testdata.toString());
+ test.done();
+ },
+ list: async function (test) {
+ test.expect(4);
+ let res = await sf.list();
+ console.log(res);
+ test.ok(res);
+ test.ok(Array.isArray(res), "Is from type Array");
+ test.ok(res.length > 0, "Do elements exist?");
+ res.forEach(e => {
+ if (e._id === testid) {
+ test.ok(true, "Element is in List");
+ }
+ });
+ test.done();
+ },
+ update: async function (test) {
+ test.expect(5);
+ let res = await sf.update(testid, newTestData);
+ test.ok(res);
+ test.ok(res._id);
+ test.notEqual(res.version, testver, "Is new version_id generated?");
+ testver2 = res.version;
+ let res2 = await sf.get(testid);
+ test.ok(res2);
+ test.equal(res2.toString(), newTestData.toString(), "Is fetched data the updated?");
+ test.done();
+ },
+ history: async function (test) {
+ test.expect(7);
+ let his = await sf.history(testid);
+ test.ok(his);
+ test.ok(his.file);
+ test.ok(his.history);
+ test.equal(his.history.length, 1);
+ test.equal(his.history[0].version, testver);
+ test.equal(his.file.version, testver2, "Is correct version");
+ let arch = await sf.get(testid, testver);
+ test.equal(arch.toString(), testdata.toString(), "Is old version data correct");
+ test.done();
+ },
+ delete: async function (test) {
+ test.expect(1);
+ let res = await sf.delete(testid);
+ test.ok(res);
+ test.done();
+ }
+};
diff --git a/tsconfig.json b/tsconfig.json
index 6b23ea0..dbeee88 100644
--- a/tsconfig.json
+++ b/tsconfig.json
@@ -1,14 +1,13 @@
{
"compilerOptions": {
/* Basic Options */
- "watch": true,
"target": "es2017", /* Specify ECMAScript target version: 'ES3' (default), 'ES5', 'ES2015', 'ES2016', 'ES2017', or 'ESNEXT'. */
"module": "commonjs", /* Specify module code generation: 'none', 'commonjs', 'amd', 'system', 'umd', 'es2015', or 'ESNext'. */
// "lib": [], /* Specify library files to be included in the compilation: */
// "allowJs": true, /* Allow javascript files to be compiled. */
// "checkJs": true, /* Report errors in .js files. */
// "jsx": "preserve", /* Specify JSX code generation: 'preserve', 'react-native', or 'react'. */
- // "declaration": true, /* Generates corresponding '.d.ts' file. */
+ "declaration": true, /* Generates corresponding '.d.ts' file. */
// "sourceMap": true, /* Generates corresponding '.map' file. */
// "outFile": "./", /* Concatenate and emit output to single file. */
// "outDir": "./", /* Redirect output structure to the directory. */