Skip to content

Commit

Permalink
Merge pull request #29 from TransDB-de/cms-auth
Browse files Browse the repository at this point in the history
Add auth via cms account
  • Loading branch information
Feuerhamster authored Aug 25, 2024
2 parents 815720b + 748629a commit ace869a
Show file tree
Hide file tree
Showing 20 changed files with 259 additions and 474 deletions.
11 changes: 11 additions & 0 deletions .editorconfig
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
# EditorConfig is awesome: https://editorconfig.org

# top-most EditorConfig file
root = true

# Unix-style newlines with a newline ending every file
[*]
charset = utf-8
indent_style = tab
indent_size = 4

2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@
"scripts": {
"build": "npx tsc --sourceMap false",
"start": "node dist/main.js",
"dev": "node dist/main.js --dev"
"dev": "npx tsc --sourceMap true && node dist/main.js --dev"
},
"repository": {
"type": "git",
Expand Down
34 changes: 34 additions & 0 deletions src/controllers/access.controller.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
import {
Controller,
Middleware,
Post,
} from "@overnightjs/core";
import { IRequest, IResponse } from "express";
import rateLimit from "express-rate-limit";

import {
LoginBody,
} from "../models/request/users.request.js";
import validate from "../middleware/validation.middleware.js";

import * as UserService from "../services/users.service.js";
import { config } from "../services/config.service.js";

const loginRateLimiter = rateLimit({
windowMs: config.rateLimit.login.timeframeMinutes * 60 * 1000,
max: config.rateLimit.login.maxRequests,
});

@Controller("access")
export default class UsersController {
@Post("login")
@Middleware(loginRateLimiter)
@Middleware(validate(LoginBody))
async login(req: IRequest<LoginBody>, res: IResponse) {
let login = await UserService.login(req.body);

if (!login) return res.error!("wrong_credentials");

res.send(login);
}
}
115 changes: 0 additions & 115 deletions src/controllers/users.controller.ts

This file was deleted.

11 changes: 11 additions & 0 deletions src/graphql/management-users.gql
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
query {
management_users {
user {
id
first_name
last_name
}
status
admin
}
}
7 changes: 7 additions & 0 deletions src/graphql/user-me.gql
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
query {
users_me {
id
first_name
last_name
}
}
7 changes: 7 additions & 0 deletions src/graphql/users.gql
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
query {
users {
id
first_name
last_name
}
}
7 changes: 2 additions & 5 deletions src/main.ts
Original file line number Diff line number Diff line change
Expand Up @@ -14,13 +14,10 @@ if(!process.argv.includes("--dev")) {

Database.purgeBackups();

// Database
Database.events.connected = async () => {
await UserService.generateDefaultUserIfRequired();
};

Database.connect();

UserService.loadUserNameCache();

// Start server
const server = new TransDBBackendServer();
server.start(Config.config.web.port);
Expand Down
2 changes: 1 addition & 1 deletion src/models/database/entry.model.ts
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@ export interface DatabaseEntry<io extends "in" | "out"> {
approvedTimestamp?: number,

/** id of user who approved entry */
approvedBy?: io extends "in" ? ObjectId : string,
approvedBy?: string,
distance?: io extends "out" ? number : undefined

possibleDuplicate?: io extends "in" ? ObjectId : string
Expand Down
31 changes: 0 additions & 31 deletions src/models/database/user.model.ts

This file was deleted.

12 changes: 4 additions & 8 deletions src/models/response/users.response.ts
Original file line number Diff line number Diff line change
@@ -1,11 +1,7 @@
import { DatabaseUser } from "../../models/database/user.model.js"
import ResponseBody from "../../models/response.js"

export interface PublicUser extends Pick< DatabaseUser<"out">, "username" | "email" | "registerDate" | "lastLogin" | "admin"> {
password?: never;
}


export interface PasswordReset extends ResponseBody {
password: string;
export interface PublicUser extends ResponseBody {
id: string;
username: string;
admin: boolean;
}
4 changes: 2 additions & 2 deletions src/server.ts
Original file line number Diff line number Diff line change
Expand Up @@ -33,14 +33,14 @@ export default class TransDBBackendServer extends Server {
const EntriesController = (await import("./controllers/entries.controller.js")).default;
const GeodataController = (await import("./controllers/geodata.controller.js")).default;
const ReportController = (await import("./controllers/report.controller.js")).default;
const UsersController = (await import("./controllers/users.controller.js")).default;
const AccessController = (await import("./controllers/access.controller.js")).default;

super.addControllers([
new DefaultController(),
new EntriesController(),
new GeodataController(),
new ReportController(),
new UsersController()
new AccessController()
]);
}

Expand Down
48 changes: 45 additions & 3 deletions src/services/cms.service.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,24 @@
import axios from "axios";
import { ECMSTicketType } from "../types/cms";
import { CMSManagementUser, CMSManagementUsersGQLResponse, CMSUser, CMSUserMeGQLResponse, type CMSUsersGQLResponse, ECMSTicketType } from "../types/cms.js";
import { config } from "./config.service.js";
import { loadGQLFiles } from "../util/graphql.util.js";

type GQLQueryNames = "users" | "user-me" | "management-users";

const gqlQueries = loadGQLFiles<GQLQueryNames>("./src/graphql/");

export function cmsRequestFactory(path: string, accessToken?: string) {
const url = new URL(path, config.cms.url).href;

const token = accessToken ? accessToken : config.cms.access_token;

const options = { headers: { Authorization: "Bearer " + token } };

return {
url,
options
}
}

export async function createTicket(title: string, entryId: string | null, type: ECMSTicketType, description: string | null) {
const newTicket = {
Expand All @@ -10,12 +28,36 @@ export async function createTicket(title: string, entryId: string | null, type:
entry_id: entryId
};

const url = new URL("/items/" + config.cms.ticket_collection, config.cms.url).href;
const { url, options } = cmsRequestFactory("/items/" + config.cms.ticket_collection);

try {
await axios.post(url, newTicket, { headers: { Authorization: "Bearer " + config.cms.access_token} });
await axios.post(url, newTicket, options);
return true;
} catch(e) {
return false;
}
}

export async function fetchUsers(): Promise<CMSUser[]> {
const query = gqlQueries.get("users");
const { url, options } = cmsRequestFactory("/graphql/system");

const res = await axios.post<CMSUsersGQLResponse>(url, query, options);
return res.data.data.users;
}

export async function getOwnUser(accessToken: string): Promise<CMSUser> {
const query = gqlQueries.get("user-me");
const { url, options } = cmsRequestFactory("/graphql/system", accessToken);

const res = await axios.post<CMSUserMeGQLResponse>(url, query, options);
return res.data.data.users_me;
}

export async function getManagementUsers(): Promise<CMSManagementUser[]> {
const query = gqlQueries.get("management-users");
const { url, options } = cmsRequestFactory("/graphql");

const res = await axios.post<CMSManagementUsersGQLResponse>(url, query, options);
return res.data.data.management_users;
}
6 changes: 5 additions & 1 deletion src/services/config.service.ts
Original file line number Diff line number Diff line change
Expand Up @@ -62,7 +62,11 @@ const defaultConfig = {
cms: {
url: "",
access_token: "",
ticket_collection: ""
ticket_collection: "",
access_colelction: ""
},
legacyUsers: {

}
};

Expand Down
Loading

0 comments on commit ace869a

Please sign in to comment.