Login and Register API added, further info shared between Owners
This commit is contained in:
@@ -7,7 +7,8 @@
|
|||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
import { Context } from "https://deno.land/x/oak/mod.ts";
|
import { Context } from "https://deno.land/x/oak/mod.ts";
|
||||||
import { hash } from "node:crypto";
|
import { encodeHex } from "jsr:@std/encoding/hex";
|
||||||
|
// import { hash } from "node:crypto";
|
||||||
|
|
||||||
export type ApiResponse = {
|
export type ApiResponse = {
|
||||||
status: number;
|
status: number;
|
||||||
@@ -37,8 +38,18 @@ const errorResponse = (ctx: Context, status: number, message: string): void => {
|
|||||||
/**
|
/**
|
||||||
* @description Hashing Function for Passwords/etc
|
* @description Hashing Function for Passwords/etc
|
||||||
* @param password The password to hash
|
* @param password The password to hash
|
||||||
* Works only up to 5 Megabytes
|
|
||||||
*/
|
*/
|
||||||
const hashPassword = async (password: string): Promise<string> => {
|
const hashPassword = async(password: string): Promise<string> => {
|
||||||
return hash("sha256", password);
|
const to_hash = password;
|
||||||
|
const buffer = new TextEncoder().encode(to_hash);
|
||||||
|
const hash_buffer = await crypto.subtle.digest("SHA-256", buffer);
|
||||||
|
const hash = await encodeHex(hash_buffer);
|
||||||
|
|
||||||
|
return hash;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export {
|
||||||
|
sendResponse,
|
||||||
|
errorResponse,
|
||||||
|
hashPassword
|
||||||
|
};
|
||||||
|
|||||||
84
api/main.ts
84
api/main.ts
@@ -32,8 +32,8 @@ router
|
|||||||
|
|
||||||
// Account routes
|
// Account routes
|
||||||
router
|
router
|
||||||
.post("/api/account/login", () => {}) // TODO
|
.post("/api/account/login", api_login) // TODO
|
||||||
.post("/api/account/register", () => {}) // TODO
|
.post("/api/account/register", api_register) // TODO
|
||||||
.post("/api/account/logout", () => {}) // TODO
|
.post("/api/account/logout", () => {}) // TODO
|
||||||
.post("/api/account/password/forgot", () => {}) // TODO
|
.post("/api/account/password/forgot", () => {}) // TODO
|
||||||
.post("/api/account/password/reset", () => {}) // TODO
|
.post("/api/account/password/reset", () => {}) // TODO
|
||||||
@@ -52,7 +52,7 @@ router
|
|||||||
// User routes
|
// User routes
|
||||||
router
|
router
|
||||||
.get("/api/users", api_getAllUsers)
|
.get("/api/users", api_getAllUsers)
|
||||||
.get("/api/user/:id/info", api_user_getInfo);
|
.get("/api/user/:id/info", api_user_getInfo); // @error GEHT NICHT
|
||||||
|
|
||||||
// Post routes
|
// Post routes
|
||||||
router
|
router
|
||||||
@@ -69,6 +69,7 @@ router
|
|||||||
* Currently not implemented
|
* Currently not implemented
|
||||||
* Middleware
|
* Middleware
|
||||||
*/
|
*/
|
||||||
|
|
||||||
async function authenticator(ctx: Context, next: Next): Promise<void> {
|
async function authenticator(ctx: Context, next: Next): Promise<void> {
|
||||||
const authHeader = ctx.request.headers.get('Authorization');
|
const authHeader = ctx.request.headers.get('Authorization');
|
||||||
|
|
||||||
@@ -111,8 +112,7 @@ async function tokenChecker(ctx: Context, next: Next): Promise<void> {
|
|||||||
*/
|
*/
|
||||||
}
|
}
|
||||||
|
|
||||||
|
async function api_getAllUsers(ctx: Context): Promise<void> {
|
||||||
async function api_getAllUsers(ctx: any): Promise<void> {
|
|
||||||
const getUsers = await db_utils.getAllUsersFromDB();
|
const getUsers = await db_utils.getAllUsersFromDB();
|
||||||
ctx.response.body = getUsers;
|
ctx.response.body = getUsers;
|
||||||
}
|
}
|
||||||
@@ -129,33 +129,89 @@ async function api_user_getInfo(ctx: any): Promise<void> {
|
|||||||
|
|
||||||
try {
|
try {
|
||||||
const user = await db_utils.getAllUserInfoByID(id);
|
const user = await db_utils.getAllUserInfoByID(id);
|
||||||
|
if (user === null || user === undefined) {
|
||||||
if (!user) {
|
helper_utils.errorResponse(ctx, 404, "User not found");
|
||||||
ctx.response.status = 404; // Not Found status/Doesn't exist
|
|
||||||
ctx.response.body = { error: "User not found" };
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
ctx.response.body = user;
|
ctx.response.body = user;
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
ctx.response.status = 500; // Internal Server Error status
|
helper_utils.errorResponse(ctx, 500, "Internal Server Error");
|
||||||
ctx.response.body = { error: "Error" };
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
// Posts
|
// Posts
|
||||||
async function api_posts_getAll(ctx: any): Promise<void> {
|
async function api_posts_getAll(ctx: Context): Promise<void> {
|
||||||
const posts = await db_utils.getPostsFromDB();
|
const posts = await db_utils.getPostsFromDB();
|
||||||
ctx.response.body = posts;
|
ctx.response.body = posts;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Comments
|
// Comments
|
||||||
|
|
||||||
|
// login/register
|
||||||
|
async function api_register(ctx: Context): Promise<void> {
|
||||||
|
try {
|
||||||
|
const body = ctx.request.body;
|
||||||
|
const result = await body.json();
|
||||||
|
const { username, password, userGroup, displayname, user_email, firstname, surname} = result;
|
||||||
|
const account_created = `${Math.floor(Date.now() / 1000)}${new Date().toLocaleDateString('en-GB').split('/').join('.')}`;
|
||||||
|
|
||||||
|
|
||||||
|
if ( !username || !password || !userGroup || !displayname || !user_email || !firstname || !surname) {
|
||||||
|
helper_utils.errorResponse(ctx, 400, "Missing required fields");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
const hash = await helper_utils.hashPassword(password);
|
||||||
|
const userId = await db_utils.registerUser(username, hash, userGroup, displayname, user_email, firstname, surname, account_created);
|
||||||
|
helper_utils.sendResponse(ctx, { status: 200, body: `Registered under name: ${userId}` });
|
||||||
|
} catch (error) {
|
||||||
|
console.log(error);
|
||||||
|
helper_utils.errorResponse(ctx, 500, "Invalid request");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
async function api_login(ctx: Context): Promise<string> {
|
||||||
|
try {
|
||||||
|
const body = ctx.request.body;
|
||||||
|
const result = await body.json();
|
||||||
|
const { username, password } = result;
|
||||||
|
|
||||||
|
if (!username || !password) {
|
||||||
|
helper_utils.errorResponse(ctx, 400, "Missing required fields");
|
||||||
|
return "Error";
|
||||||
|
}
|
||||||
|
|
||||||
|
const user = await db_utils.getUserByUsername(username);
|
||||||
|
if (!user) {
|
||||||
|
helper_utils.errorResponse(ctx, 404, "User not found");
|
||||||
|
return "Error";
|
||||||
|
}
|
||||||
|
|
||||||
|
const hash = await helper_utils.hashPassword(password);
|
||||||
|
if (user.password !== hash) {
|
||||||
|
helper_utils.errorResponse(ctx, 401, "Invalid password");
|
||||||
|
return "Error";
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
} catch (error) {
|
||||||
|
console.log(error);
|
||||||
|
helper_utils.errorResponse(ctx, 500, "Invalid request");
|
||||||
|
return "Error";
|
||||||
|
}
|
||||||
|
|
||||||
|
return "Success";
|
||||||
|
}
|
||||||
|
|
||||||
// Filtering
|
// Filtering
|
||||||
|
|
||||||
// +++ APP ---------------------------------------------------------- //
|
// +++ APP ---------------------------------------------------------- //
|
||||||
app.use(oakCors());
|
app.use(oakCors({
|
||||||
|
origin: '*',
|
||||||
|
credentials: true,
|
||||||
|
}));
|
||||||
app.use(router.routes());
|
app.use(router.routes());
|
||||||
app.use(router.allowedMethods());
|
app.use(router.allowedMethods());
|
||||||
|
|
||||||
|
|||||||
Binary file not shown.
@@ -173,6 +173,17 @@ async function getAllUsersFromDB(): Promise<Accounts[]> {
|
|||||||
return await queryDatabase<Accounts>(query, [], mapAccountRow);
|
return await queryDatabase<Accounts>(query, [], mapAccountRow);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param username
|
||||||
|
* @returns Returns the Accounts for the User with the given username
|
||||||
|
*/
|
||||||
|
async function getUserByUsername(username: string): Promise<Accounts> {
|
||||||
|
const query = `SELECT * FROM accounts WHERE user_username = '${username}'`;
|
||||||
|
const params:string[] = [];
|
||||||
|
const result = await queryDatabase<Accounts>(query, params, mapAccountRow);
|
||||||
|
return result[0];
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @param post_id The ID of the Post to get the Comments for. Not required
|
* @param post_id The ID of the Post to get the Comments for. Not required
|
||||||
* @description If no post_id is provided, all Comments will be returned
|
* @description If no post_id is provided, all Comments will be returned
|
||||||
@@ -192,6 +203,7 @@ async function getCommentsFromDB(post_id?: number): Promise<Comments[]> {
|
|||||||
* @returns Array of Comments for the Comment, or an empty Array if there are no Comments
|
* @returns Array of Comments for the Comment, or an empty Array if there are no Comments
|
||||||
*/
|
*/
|
||||||
function getCommentsForComments(comment_id: number) {
|
function getCommentsForComments(comment_id: number) {
|
||||||
|
// Will be rewritten to use the queryDatabase function
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -221,11 +233,34 @@ function filterForTextPosts(posts_to_filter: Array<any>) {
|
|||||||
return [];
|
return [];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// Register/Login/User
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param user The name of the User to add
|
||||||
|
* @param password The password of the User to add
|
||||||
|
* @returns Array of Posts from the User, or an empty Array if the User doesn't exist or has no Posts
|
||||||
|
*/
|
||||||
|
function registerUser (user: string, password: string, userGroup: string, displayname: string, user_email: string, firstname: string, surname: string, account_created: string): string {
|
||||||
|
const query_user_exists = `SELECT * FROM accounts WHERE user_username = '${user}'`;
|
||||||
|
if (!query_user_exists) {
|
||||||
|
return "noUser";
|
||||||
|
}
|
||||||
|
|
||||||
|
const query_add_user = `INSERT INTO accounts (user_username, password, user_group, user_displayname, user_email, firstname, surname, account_created) VALUES ('${user}', '${password}', '${userGroup}', '${displayname}', '${user_email}', '${firstname}', '${surname}', '${account_created}')`;
|
||||||
|
db.query(query_add_user);
|
||||||
|
console.log(`New user: ${user}`)
|
||||||
|
|
||||||
|
return "newUser";
|
||||||
|
}
|
||||||
|
|
||||||
// Exporting all functions as this is a module
|
// Exporting all functions as this is a module
|
||||||
export {
|
export {
|
||||||
|
registerUser,
|
||||||
createDatabaseIfNotExist,
|
createDatabaseIfNotExist,
|
||||||
getAllUserInfoByID,
|
getAllUserInfoByID,
|
||||||
getAllUsersFromDB,
|
getAllUsersFromDB,
|
||||||
|
getUserByUsername,
|
||||||
getCommentsForComments,
|
getCommentsForComments,
|
||||||
getCommentsFromDB,
|
getCommentsFromDB,
|
||||||
getPostsFromDB,
|
getPostsFromDB,
|
||||||
|
|||||||
1
deno.lock
generated
1
deno.lock
generated
@@ -6,6 +6,7 @@
|
|||||||
"jsr:@std/bytes@1": "1.0.2",
|
"jsr:@std/bytes@1": "1.0.2",
|
||||||
"jsr:@std/bytes@^1.0.2": "1.0.2",
|
"jsr:@std/bytes@^1.0.2": "1.0.2",
|
||||||
"jsr:@std/crypto@1": "1.0.3",
|
"jsr:@std/crypto@1": "1.0.3",
|
||||||
|
"jsr:@std/encoding@*": "1.0.5",
|
||||||
"jsr:@std/encoding@1": "1.0.5",
|
"jsr:@std/encoding@1": "1.0.5",
|
||||||
"jsr:@std/encoding@^1.0.5": "1.0.5",
|
"jsr:@std/encoding@^1.0.5": "1.0.5",
|
||||||
"jsr:@std/http@1": "1.0.9",
|
"jsr:@std/http@1": "1.0.9",
|
||||||
|
|||||||
Reference in New Issue
Block a user