Skip to content

Commit

Permalink
Merge pull request #3 from tago-io/feature/auth-system
Browse files Browse the repository at this point in the history
Feature: Authentication and Setup
  • Loading branch information
matheuslbenachio authored Jul 11, 2022
2 parents 971508f + 112c35d commit 44f4147
Show file tree
Hide file tree
Showing 187 changed files with 8,185 additions and 5,298 deletions.
4 changes: 3 additions & 1 deletion .vscode/settings.json
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@
"IURL",
"linuxstatic",
"Lucida",
"masterpassword",
"onentry",
"outfile",
"Parens",
Expand All @@ -50,6 +51,7 @@
"TCORE",
"tcoreignore",
"testid",
"tinycolor"
"tinycolor",
"unattach"
],
}
7,823 changes: 3,247 additions & 4,576 deletions package-lock.json

Large diffs are not rendered by default.

4 changes: 3 additions & 1 deletion package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "@tago-io/tcore",
"version": "0.4.1",
"version": "0.5.0",
"author": "Tago LLC",
"description": "TCore by TagoIO",
"license": "MIT",
Expand All @@ -13,6 +13,8 @@
"packages/tcore-sdk",
"packages/tcore-shared",
"packages/tcore-console",
"packages/tcore-api",
"packages/tcore-cli",
"packages/*"
],
"keywords": [
Expand Down
12 changes: 6 additions & 6 deletions packages/tcore-api/package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "@tago-io/tcore-api",
"version": "0.4.1",
"version": "0.5.0",
"private": true,
"description": "TCore API",
"author": "Tago LLC",
Expand Down Expand Up @@ -55,18 +55,18 @@
"@types/method-override": "0.0.32",
"@types/node": "16.7.1",
"@types/tar": "6.1.0",
"@typescript-eslint/eslint-plugin": "4.29.3",
"@typescript-eslint/parser": "4.29.3",
"@typescript-eslint/eslint-plugin": "5.14.0",
"@typescript-eslint/parser": "5.14.0",
"eslint": "7.32.0",
"eslint-config-prettier": "8.3.0",
"eslint-import-resolver-typescript": "2.4.0",
"eslint-plugin-import": "2.24.1",
"eslint-plugin-jest": "24.4.0",
"eslint-plugin-import": "2.26.0",
"eslint-plugin-jest": "26.5.3",
"eslint-plugin-prettier": "3.4.1",
"jest": "27.0.6",
"prettier": "2.3.2",
"ts-jest": "27.0.5",
"ts-node": "10.2.1",
"ts-node": "10.8.2",
"typescript": "4.3.5"
}
}
59 changes: 56 additions & 3 deletions packages/tcore-api/src/Controllers/APIController.ts
Original file line number Diff line number Diff line change
@@ -1,9 +1,12 @@
import { IncomingHttpHeaders } from "http";
import express, { Request, Response } from "express";
import { ZodTypeAny } from "zod";
import { getDeviceByToken } from "../Services/Device";
import { IAccountToken, IDeviceToken } from "@tago-io/tcore-sdk/types";
import { getDeviceByToken, getDeviceToken } from "../Services/Device";
import { getAccountToken } from "../Services/Account/Account";
import { checkMasterPassword } from "../Services/Settings";

type TResourceType = "device" | "analysis";
type TResourceType = "device" | "account";
type TPermission = "full" | "write" | "read";

interface ISetupToken {
Expand Down Expand Up @@ -95,7 +98,14 @@ abstract class APIController<BodyParams = any, QueryStringParams = any, URLParam
* Runs the whole routine.
*/
private async init() {
// await this.resolveToken();
try {
await this.resolveAuth();
} catch (ex: any) {
this.body = ex?.message || undefined;
this.res.statusCode = 401;
this.res.json({ status: false, result: this.body });
return;
}

let errorOn = "unknown";
try {
Expand Down Expand Up @@ -155,6 +165,49 @@ abstract class APIController<BodyParams = any, QueryStringParams = any, URLParam
}
}

/**
* Validates and resolves account and device tokens.
*/
private async resolveAuth() {
let accountToken: IAccountToken | null = null;
let deviceToken: IDeviceToken | null = null;

const containAnonymousToken = this.setup.allowTokens.some((x) => x.resource === "anonymous");
if (containAnonymousToken) {
// valid by default
return;
}

for (const allowed of this.setup.allowTokens || []) {
if (allowed.resource === "account") {
if (!accountToken) {
accountToken = await getAccountToken(this.rawToken as string).catch(() => null);
}
if (accountToken?.permission === "full" || accountToken?.permission === allowed.permission) {
// valid permission
return;
}
if (this.req.headers.masterpassword) {
const matches = await checkMasterPassword(this.req.headers.masterpassword as string);
if (matches) {
return;
}
}
}
if (allowed.resource === "device") {
if (!deviceToken) {
deviceToken = await getDeviceToken(this.rawToken as string).catch(() => null);
}
if (deviceToken?.permission === "full" || deviceToken?.permission === allowed.permission) {
// valid permission
return;
}
}
}

throw new Error("Authorization denied");
}

/**
*/
private getToken(headers: IncomingHttpHeaders): string | void {
Expand Down
64 changes: 64 additions & 0 deletions packages/tcore-api/src/Controllers/Account/Account.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,64 @@
import { Application } from "express";
import { z } from "zod";
import { IAccountCreate, zAccountCreate } from "@tago-io/tcore-sdk/types";
import { createAccount, getAccountByToken, login } from "../../Services/Account/Account";
import APIController, { ISetupController, warm } from "../APIController";

const zAccountLoginBody = z.object({
username: z.string(),
password: z.string(),
});

/**
* Lists all the database plugins.
*/
class AccountLogin extends APIController<z.infer<typeof zAccountLoginBody>, void, void> {
setup: ISetupController = {
allowTokens: [{ permission: "any", resource: "anonymous" }],
zBodyParser: zAccountLoginBody,
};

public async main() {
const { username, password } = this.bodyParams;
const response = await login(username, password);
this.body = response;
}
}

/**
* Checks if there is at least one account registered.
*/
class InfoAccount extends APIController<void, void, void> {
setup: ISetupController = {
allowTokens: [{ permission: "read", resource: "account" }],
};

public async main() {
const response = await getAccountByToken(this.rawToken as string);
this.body = response;
}
}

/**
* Creates a new device.
*/
class CreateAccount extends APIController<IAccountCreate, void, void> {
setup: ISetupController = {
allowTokens: [{ permission: "write", resource: "account" }],
zBodyParser: zAccountCreate,
};

public async main() {
const response = await createAccount(this.bodyParams);
this.body = response;
}
}

/**
* Exports the auth routes.
*/
export default (app: Application) => {
app.get("/account", warm(InfoAccount));
app.post("/account", warm(CreateAccount));
app.post("/account/login", warm(AccountLogin));
};
12 changes: 6 additions & 6 deletions packages/tcore-api/src/Controllers/Action.ts
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ const zURLParamsID = z.object({
*/
class ListActions extends APIController<void, IActionListQuery, void> {
setup: ISetupController = {
allowTokens: [],
allowTokens: [{ permission: "read", resource: "account" }],
zQueryStringParser: zActionListQuery,
};

Expand All @@ -38,7 +38,7 @@ class ListActions extends APIController<void, IActionListQuery, void> {
*/
class GetActionInfo extends APIController<void, void, z.infer<typeof zURLParamsID>> {
setup: ISetupController = {
allowTokens: [],
allowTokens: [{ permission: "read", resource: "account" }],
zURLParamsParser: zURLParamsID,
};

Expand All @@ -53,7 +53,7 @@ class GetActionInfo extends APIController<void, void, z.infer<typeof zURLParamsI
*/
class DeleteAction extends APIController<void, void, z.infer<typeof zURLParamsID>> {
setup: ISetupController = {
allowTokens: [],
allowTokens: [{ permission: "write", resource: "account" }],
zURLParamsParser: zURLParamsID,
};

Expand All @@ -67,7 +67,7 @@ class DeleteAction extends APIController<void, void, z.infer<typeof zURLParamsID
*/
class EditAction extends APIController<IActionEdit, void, z.infer<typeof zURLParamsID>> {
setup: ISetupController = {
allowTokens: [],
allowTokens: [{ permission: "write", resource: "account" }],
zBodyParser: zActionEdit,
zURLParamsParser: zURLParamsID,
};
Expand All @@ -82,13 +82,13 @@ class EditAction extends APIController<IActionEdit, void, z.infer<typeof zURLPar
*/
class CreateAction extends APIController<IActionCreate, void, void> {
setup: ISetupController = {
allowTokens: [],
allowTokens: [{ permission: "write", resource: "account" }],
zBodyParser: zActionCreate,
};

public async main() {
const response = await createAction(this.bodyParams);
this.body = response;
this.body = { action: response };
}
}

Expand Down
14 changes: 7 additions & 7 deletions packages/tcore-api/src/Controllers/Analysis.ts
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ const zURLParamsID = z.object({
*/
class ListAnalyses extends APIController<void, IAnalysisListQuery, void> {
setup: ISetupController = {
allowTokens: [],
allowTokens: [{ permission: "read", resource: "account" }],
zQueryStringParser: zAnalysisListQuery,
};

Expand All @@ -39,7 +39,7 @@ class ListAnalyses extends APIController<void, IAnalysisListQuery, void> {
*/
class GetAnalysisInfo extends APIController<void, void, z.infer<typeof zURLParamsID>> {
setup: ISetupController = {
allowTokens: [],
allowTokens: [{ permission: "read", resource: "account" }],
zURLParamsParser: zURLParamsID,
};

Expand All @@ -54,7 +54,7 @@ class GetAnalysisInfo extends APIController<void, void, z.infer<typeof zURLParam
*/
class DeleteAnalysis extends APIController<void, void, z.infer<typeof zURLParamsID>> {
setup: ISetupController = {
allowTokens: [],
allowTokens: [{ permission: "write", resource: "account" }],
zURLParamsParser: zURLParamsID,
};

Expand All @@ -68,7 +68,7 @@ class DeleteAnalysis extends APIController<void, void, z.infer<typeof zURLParams
*/
class RunAnalysis extends APIController<any, void, z.infer<typeof zURLParamsID>> {
setup: ISetupController = {
allowTokens: [],
allowTokens: [{ permission: "write", resource: "account" }],
zURLParamsParser: zURLParamsID,
zBodyParser: z.any(),
};
Expand All @@ -83,7 +83,7 @@ class RunAnalysis extends APIController<any, void, z.infer<typeof zURLParamsID>>
*/
class EditAnalysis extends APIController<IAnalysisEdit, void, z.infer<typeof zURLParamsID>> {
setup: ISetupController = {
allowTokens: [],
allowTokens: [{ permission: "write", resource: "account" }],
zBodyParser: zAnalysisEdit,
zURLParamsParser: zURLParamsID,
};
Expand All @@ -98,13 +98,13 @@ class EditAnalysis extends APIController<IAnalysisEdit, void, z.infer<typeof zUR
*/
class CreateAnalysis extends APIController<IAnalysisCreate, void, void> {
setup: ISetupController = {
allowTokens: [],
allowTokens: [{ permission: "write", resource: "account" }],
zBodyParser: zAnalysisCreate,
};

public async main() {
const response = await createAnalysis(this.bodyParams);
this.body = response;
this.body = { id: response };
}
}

Expand Down
36 changes: 0 additions & 36 deletions packages/tcore-api/src/Controllers/Device/Device.test.ts

This file was deleted.

Loading

0 comments on commit 44f4147

Please sign in to comment.