Ver Fonte

Websocket working and newt auth working

Owen Schwartz há 8 meses atrás
pai
commit
03650634ee

+ 11 - 0
bruno/Newt/Create Newt.bru

@@ -0,0 +1,11 @@
+meta {
+  name: Create Newt
+  type: http
+  seq: 2
+}
+
+get {
+  url: http://localhost:3000/api/v1/newt
+  body: none
+  auth: none
+}

+ 18 - 0
bruno/Newt/Get Token.bru

@@ -0,0 +1,18 @@
+meta {
+  name: Get Token
+  type: http
+  seq: 1
+}
+
+get {
+  url: http://localhost:3000/api/v1/auth/newt/get-token
+  body: json
+  auth: none
+}
+
+body:json {
+  {
+   "newtId": "o0d4rdxq3stnz7b",
+    "secret": "sy7l09fnaesd03iwrfp9m3qf0ryn19g0zf3dqieaazb4k7vk"
+  }
+}

+ 5 - 0
server/routers/external.ts

@@ -24,6 +24,7 @@ import {
 import { verifyUserHasAction } from "./auth/verifyUserHasAction";
 import { ActionsEnum } from "@server/auth/actions";
 import { verifyUserIsOrgOwner } from "./auth/verifyUserIsOrgOwner";
+import { createNewt, getToken } from "./newt";
 
 // Root routes
 export const unauthenticated = Router();
@@ -353,6 +354,8 @@ authenticated.delete(
 //     role.removeRoleAction
 // );
 
+authenticated.put("/newt", createNewt);
+
 // Auth routes
 export const authRouter = Router();
 unauthenticated.use("/auth", authRouter);
@@ -367,6 +370,8 @@ authRouter.use(
 authRouter.put("/signup", auth.signup);
 authRouter.post("/login", auth.login);
 authRouter.post("/logout", auth.logout);
+authRouter.post('/newt/get-token', getToken);
+
 authRouter.post("/2fa/enable", verifySessionUserMiddleware, auth.verifyTotp);
 authRouter.post(
     "/2fa/request",

+ 91 - 0
server/routers/newt/createNewt.ts

@@ -0,0 +1,91 @@
+import { NextFunction, Request, Response } from "express";
+import db from "@server/db";
+import { hash } from "@node-rs/argon2";
+import HttpCode from "@server/types/HttpCode";
+import { z } from "zod";
+import { newts } from "@server/db/schema";
+import createHttpError from "http-errors";
+import response from "@server/utils/response";
+import { SqliteError } from "better-sqlite3";
+import moment from "moment";
+import {
+    generateId,
+    generateSessionToken,
+} from "@server/auth";
+import { createNewtSession } from "@server/auth/newt";
+
+export const createNewtBodySchema = z.object({});
+
+export type CreateNewtBody = z.infer<typeof createNewtBodySchema>;
+
+export type CreateNewtResponse = {
+    token: string;
+    newtId: string;
+    secret: string;
+};
+
+export async function createNewt(
+    req: Request,
+    res: Response,
+    next: NextFunction
+): Promise<any> {
+    try {
+
+        // generate a newtId and secret
+        const secret = generateId(48);
+        const secretHash = await hash(secret, {
+            memoryCost: 19456,
+            timeCost: 2,
+            outputLen: 32,
+            parallelism: 1,
+        });
+
+        const newtId = generateId(15);
+
+        await db.insert(newts).values({
+            newtId: newtId,
+            secretHash,
+            dateCreated: moment().toISOString(),
+        });
+
+        // give the newt their default permissions:
+        // await db.insert(newtActions).values({
+        //     newtId: newtId,
+        //     actionId: ActionsEnum.createOrg,
+        //     orgId: null,
+        // });
+
+        const token = generateSessionToken();
+        await createNewtSession(token, newtId);
+
+        return response<CreateNewtResponse>(res, {
+            data: {
+                newtId,
+                secret,
+                token,
+            },
+            success: true,
+            error: false,
+            message: "Newt created successfully",
+            status: HttpCode.OK,
+        });
+    } catch (e) {
+        if (e instanceof SqliteError && e.code === "SQLITE_CONSTRAINT_UNIQUE") {
+            return next(
+                createHttpError(
+                    HttpCode.BAD_REQUEST,
+                    "A newt with that email address already exists"
+                )
+            );
+        } else {
+            console.error(e);
+            
+            return next(
+                createHttpError(
+                    HttpCode.INTERNAL_SERVER_ERROR,
+                    "Failed to create newt"
+                )
+            );
+        }
+    }
+}

+ 5 - 5
server/routers/auth/newtGetToken.ts → server/routers/newt/getToken.ts

@@ -13,18 +13,17 @@ import { NextFunction, Request, Response } from "express";
 import createHttpError from "http-errors";
 import { z } from "zod";
 import { fromError } from "zod-validation-error";
-import config from "@server/config";
-import { validateNewtSessionToken } from "@server/auth/newt";
+import { createNewtSession, validateNewtSessionToken } from "@server/auth/newt";
 
 export const newtGetTokenBodySchema = z.object({
-    newtId: z.string().email(),
+    newtId: z.string(),
     secret: z.string(),
     token: z.string().optional(),
 });
 
 export type NewtGetTokenBody = z.infer<typeof newtGetTokenBodySchema>;
 
-export async function newtGetToken(
+export async function getToken(
     req: Request,
     res: Response,
     next: NextFunction
@@ -93,7 +92,7 @@ export async function newtGetToken(
         }
 
         const resToken = generateSessionToken();
-        await createSession(resToken, existingNewt.newtId);
+        await createNewtSession(resToken, existingNewt.newtId);
 
         return response<{ token: string }>(res, {
             data: {
@@ -105,6 +104,7 @@ export async function newtGetToken(
             status: HttpCode.OK,
         });
     } catch (e) {
+        console.error(e);
         return next(
             createHttpError(
                 HttpCode.INTERNAL_SERVER_ERROR,

+ 2 - 0
server/routers/newt/index.ts

@@ -0,0 +1,2 @@
+export * from "./createNewt";
+export * from "./getToken";

+ 0 - 3
server/routers/ws.ts

@@ -6,7 +6,6 @@ import { Socket } from 'net';
 import { Newt, newts, NewtSession } from '@server/db/schema';
 import { eq } from 'drizzle-orm';
 import db from '@server/db';
-import { newtGetToken } from './auth';
 import { validateNewtSessionToken } from '@server/auth/newt';
 
 // Custom interfaces
@@ -61,8 +60,6 @@ router.get('/ws', (req: Request, res: Response) => {
     res.status(200).send('WebSocket endpoint');
 });
 
-router.get('/ws/auth/newtGetToken', newtGetToken);
-
 // Set up WebSocket server handling
 const handleWSUpgrade = (server: HttpServer): void => {
     server.on('upgrade', async (request: WebSocketRequest, socket: Socket, head: Buffer) => {

+ 15 - 0
src/app/[orgId]/settings/sites/components/SitesTable.tsx

@@ -13,6 +13,8 @@ import { ArrowUpDown, MoreHorizontal } from "lucide-react";
 import Link from "next/link";
 import { useRouter } from "next/navigation";
 import api from "@app/api";
+import { authCookieHeader } from "@app/api/cookies";
+import { AxiosResponse } from "axios";
 
 export type SiteRow = {
     id: number;
@@ -120,7 +122,17 @@ type SitesTableProps = {
 export default function SitesTable({ sites, orgId }: SitesTableProps) {
     const router = useRouter();
 
+    const callApi = async () => {
+
+        const res = await api.put<AxiosResponse<any>>(
+            `/newt`
+        );
+        console.log(res);
+        
+    };
+
     return (
+        <>
         <SitesDataTable
             columns={columns}
             data={sites}
@@ -128,5 +140,8 @@ export default function SitesTable({ sites, orgId }: SitesTableProps) {
                 router.push(`/${orgId}/settings/sites/create`);
             }}
         />
+        <button onClick={callApi}>Create Newt</button>
+        </>
+
     );
 }