refactor(front end): login fixes to account for the forced password change

This commit is contained in:
2025-10-21 20:27:00 -05:00
parent 43abbd53f4
commit e99c409cad
26 changed files with 10435 additions and 8732 deletions

View File

@@ -0,0 +1,32 @@
meta {
name: Get Roles
type: http
seq: 2
}
get {
url: {{urlv2}}/api/auth/getuseraccess
body: none
auth: inherit
}
headers {
Content-Type: application/json
Cookie: {{session_cookie}}
}
body:json {
{
"username": "matthes01",
"password": "{{v2Password}}"
}
}
script:post-response {
bru.setEnvVar("jwtV2",res.body.token)
}
settings {
encodeUrl: true
timeout: 0
}

View File

@@ -22,9 +22,19 @@ body:json {
}
script:post-response {
bru.setEnvVar("jwtV2",res.body.token)
// grab the raw Set-Cookie header
const cookies = res.headers["set-cookie"];
// cookies is usually an array, e.g. ["auth_session=abcd123; Path=/; HttpOnly; Secure; SameSite=Lax"]
// Extract just the value part ("auth_session=abcd123")
const sessionCookie = cookies[0].split(";")[0];
// Save it as an environment variable
bru.setEnvVar("session_cookie", sessionCookie);
}
settings {
encodeUrl: true
timeout: 0
}

View File

@@ -6,17 +6,11 @@ meta {
get {
url: {{url}}/lst/api/user/roles
body: json
body: none
auth: inherit
}
body:json {
{
"module":"users",
"role":"admin"
}
}
settings {
encodeUrl: true
timeout: 0
}

View File

@@ -0,0 +1,35 @@
meta {
name: Login
type: http
seq: 10
}
post {
url: {{url}}/lst/api/user/login
body: json
auth: inherit
}
body:json {
{
"username": "cowch",
"password": "Alpla2025!"
}
}
script:post-response {
// grab the raw Set-Cookie header
const cookies = res.headers["set-cookie"];
const sessionCookie = cookies[0].split(";")[0];
// Save it as an environment variable
bru.setEnvVar("session_cookie", sessionCookie);
}
settings {
encodeUrl: true
timeout: 0
}

View File

@@ -21,4 +21,5 @@ body:json {
settings {
encodeUrl: true
timeout: 0
}

View File

@@ -32,4 +32,5 @@ script:post-response {
settings {
encodeUrl: true
timeout: 0
}

View File

@@ -5,7 +5,7 @@ meta {
}
post {
url: {{url}}/lst/api/auth/session
url: {{url}}/lst/api/auth/sign-out
body: none
auth: inherit
}
@@ -25,4 +25,5 @@ script:post-response {
settings {
encodeUrl: true
timeout: 0
}

View File

@@ -13,12 +13,12 @@ post {
body:json {
{
"scannerId": 999,
"lotNr": 26321,
"machineId": 3, // 457=22, 458=23
"printerId": 7, // 457=22, 458=23
"layoutId": 25,
"lotNr": 3314,
"machineId": 22, // 457=22, 458=23
"printerId": 22, // 457=22, 458=23
"layoutId": 7,
"numberOfCopies": 0,
"qtyToPrint": 30
"qtyToPrint": 3
}
}

View File

@@ -1,8 +1,9 @@
vars {
url: http://localhost:5500
session_cookie:
urlv2: http://usmcd1vms036:3000
urlv2: http://localhost:3000
jwtV2:
userID:
}
vars:secret [
v2Password

View File

@@ -1,9 +0,0 @@
import { createFileRoute } from '@tanstack/react-router'
export const Route = createFileRoute('/_adminLayout/admin/settings')({
component: RouteComponent,
})
function RouteComponent() {
return <div>Hello "/_adminLayout/admin/settings"!</div>
}

View File

@@ -1,11 +0,0 @@
import { createFileRoute } from '@tanstack/react-router'
export const Route = createFileRoute('/(logistics)/logistics/deliverySchedule')(
{
component: RouteComponent,
},
)
function RouteComponent() {
return <div>Hello "/(logistics)/logistics/deliverySchedule"!</div>
}

View File

@@ -1,9 +0,0 @@
import { createFileRoute } from '@tanstack/react-router'
export const Route = createFileRoute('/(mobileStuff)/_mobileLayout/')({
component: RouteComponent,
})
function RouteComponent() {
return <div>Hello "/(mobileStuff)/_mobileLayout/"!</div>
}

View File

@@ -1,15 +0,0 @@
import * as React from 'react'
import { Outlet, createRootRoute } from '@tanstack/react-router'
export const Route = createRootRoute({
component: RootComponent,
})
function RootComponent() {
return (
<React.Fragment>
<div>Hello "__root"!</div>
<Outlet />
</React.Fragment>
)
}

View File

@@ -1,9 +0,0 @@
import { createFileRoute } from '@tanstack/react-router'
export const Route = createFileRoute('/(mobileStuff)/_mobileLayout/m/')({
component: RouteComponent,
})
function RouteComponent() {
return <div>Hello "/(mobileStuff)/_mobileLayout/m/"!</div>
}

View File

@@ -47,9 +47,7 @@ export default function Nav() {
</DropdownMenuLabel>
<DropdownMenuSeparator />
<DropdownMenuItem>
{/* <Link to="/passwordChange">
Password Change
</Link> */}
<Link to="/user/profile">Profile</Link>
</DropdownMenuItem>
{/* <DropdownMenuItem>Billing</DropdownMenuItem>
<DropdownMenuItem>Team</DropdownMenuItem>

View File

@@ -15,11 +15,13 @@ import { Route as AdminLayoutRouteRouteImport } from './routes/_adminLayout/rout
import { Route as IndexRouteImport } from './routes/index'
import { Route as authLoginRouteImport } from './routes/(auth)/login'
import { Route as mobileStuffMobileLayoutRouteRouteImport } from './routes/(mobileStuff)/_mobileLayout/route'
import { Route as authUserIndexRouteImport } from './routes/(auth)/user/index'
import { Route as AdminLayoutAdminSettingsRouteImport } from './routes/_adminLayout/admin/settings'
import { Route as AdminLayoutAdminServersRouteImport } from './routes/_adminLayout/admin/servers'
import { Route as logisticsLogisticsDeliveryScheduleRouteImport } from './routes/(logistics)/logistics/deliverySchedule'
import { Route as authUserSignupRouteImport } from './routes/(auth)/user/signup'
import { Route as authUserResetpasswordRouteImport } from './routes/(auth)/user/resetpassword'
import { Route as authUserProfileRouteImport } from './routes/(auth)/user/profile'
import { Route as AdminLayoutAdminUsersRouteRouteImport } from './routes/_adminLayout/admin/_users/route'
import { Route as mobileStuffMobileLayoutMIndexRouteImport } from './routes/(mobileStuff)/_mobileLayout/m/index'
import { Route as AdminLayoutAdminUsersUsersRouteImport } from './routes/_adminLayout/admin/_users/users'
@@ -59,6 +61,11 @@ const mobileStuffMobileLayoutRouteRoute =
id: '/_mobileLayout',
getParentRoute: () => mobileStuffRoute,
} as any)
const authUserIndexRoute = authUserIndexRouteImport.update({
id: '/(auth)/user/',
path: '/user/',
getParentRoute: () => rootRouteImport,
} as any)
const AdminLayoutAdminSettingsRoute =
AdminLayoutAdminSettingsRouteImport.update({
id: '/settings',
@@ -86,6 +93,11 @@ const authUserResetpasswordRoute = authUserResetpasswordRouteImport.update({
path: '/user/resetpassword',
getParentRoute: () => rootRouteImport,
} as any)
const authUserProfileRoute = authUserProfileRouteImport.update({
id: '/(auth)/user/profile',
path: '/user/profile',
getParentRoute: () => rootRouteImport,
} as any)
const AdminLayoutAdminUsersRouteRoute =
AdminLayoutAdminUsersRouteRouteImport.update({
id: '/_users',
@@ -132,11 +144,13 @@ export interface FileRoutesByFullPath {
'/': typeof mobileStuffMobileLayoutRouteRouteWithChildren
'/login': typeof authLoginRoute
'/admin': typeof AdminLayoutAdminUsersRouteRouteWithChildren
'/user/profile': typeof authUserProfileRoute
'/user/resetpassword': typeof authUserResetpasswordRoute
'/user/signup': typeof authUserSignupRoute
'/logistics/deliverySchedule': typeof logisticsLogisticsDeliveryScheduleRoute
'/admin/servers': typeof AdminLayoutAdminServersRoute
'/admin/settings': typeof AdminLayoutAdminSettingsRoute
'/user': typeof authUserIndexRoute
'/m/cyclecounts': typeof mobileStuffMobileLayoutMCyclecountsRoute
'/m/delivery': typeof mobileStuffMobileLayoutMDeliveryRoute
'/m/relocate': typeof mobileStuffMobileLayoutMRelocateRoute
@@ -148,11 +162,13 @@ export interface FileRoutesByTo {
'/': typeof mobileStuffMobileLayoutRouteRouteWithChildren
'/login': typeof authLoginRoute
'/admin': typeof AdminLayoutAdminUsersRouteRouteWithChildren
'/user/profile': typeof authUserProfileRoute
'/user/resetpassword': typeof authUserResetpasswordRoute
'/user/signup': typeof authUserSignupRoute
'/logistics/deliverySchedule': typeof logisticsLogisticsDeliveryScheduleRoute
'/admin/servers': typeof AdminLayoutAdminServersRoute
'/admin/settings': typeof AdminLayoutAdminSettingsRoute
'/user': typeof authUserIndexRoute
'/m/cyclecounts': typeof mobileStuffMobileLayoutMCyclecountsRoute
'/m/delivery': typeof mobileStuffMobileLayoutMDeliveryRoute
'/m/relocate': typeof mobileStuffMobileLayoutMRelocateRoute
@@ -169,11 +185,13 @@ export interface FileRoutesById {
'/(auth)/login': typeof authLoginRoute
'/_adminLayout/admin': typeof AdminLayoutAdminRouteWithChildren
'/_adminLayout/admin/_users': typeof AdminLayoutAdminUsersRouteRouteWithChildren
'/(auth)/user/profile': typeof authUserProfileRoute
'/(auth)/user/resetpassword': typeof authUserResetpasswordRoute
'/(auth)/user/signup': typeof authUserSignupRoute
'/(logistics)/logistics/deliverySchedule': typeof logisticsLogisticsDeliveryScheduleRoute
'/_adminLayout/admin/servers': typeof AdminLayoutAdminServersRoute
'/_adminLayout/admin/settings': typeof AdminLayoutAdminSettingsRoute
'/(auth)/user/': typeof authUserIndexRoute
'/(mobileStuff)/_mobileLayout/m/cyclecounts': typeof mobileStuffMobileLayoutMCyclecountsRoute
'/(mobileStuff)/_mobileLayout/m/delivery': typeof mobileStuffMobileLayoutMDeliveryRoute
'/(mobileStuff)/_mobileLayout/m/relocate': typeof mobileStuffMobileLayoutMRelocateRoute
@@ -187,11 +205,13 @@ export interface FileRouteTypes {
| '/'
| '/login'
| '/admin'
| '/user/profile'
| '/user/resetpassword'
| '/user/signup'
| '/logistics/deliverySchedule'
| '/admin/servers'
| '/admin/settings'
| '/user'
| '/m/cyclecounts'
| '/m/delivery'
| '/m/relocate'
@@ -203,11 +223,13 @@ export interface FileRouteTypes {
| '/'
| '/login'
| '/admin'
| '/user/profile'
| '/user/resetpassword'
| '/user/signup'
| '/logistics/deliverySchedule'
| '/admin/servers'
| '/admin/settings'
| '/user'
| '/m/cyclecounts'
| '/m/delivery'
| '/m/relocate'
@@ -223,11 +245,13 @@ export interface FileRouteTypes {
| '/(auth)/login'
| '/_adminLayout/admin'
| '/_adminLayout/admin/_users'
| '/(auth)/user/profile'
| '/(auth)/user/resetpassword'
| '/(auth)/user/signup'
| '/(logistics)/logistics/deliverySchedule'
| '/_adminLayout/admin/servers'
| '/_adminLayout/admin/settings'
| '/(auth)/user/'
| '/(mobileStuff)/_mobileLayout/m/cyclecounts'
| '/(mobileStuff)/_mobileLayout/m/delivery'
| '/(mobileStuff)/_mobileLayout/m/relocate'
@@ -241,9 +265,11 @@ export interface RootRouteChildren {
AdminLayoutRouteRoute: typeof AdminLayoutRouteRouteWithChildren
mobileStuffRoute: typeof mobileStuffRouteWithChildren
authLoginRoute: typeof authLoginRoute
authUserProfileRoute: typeof authUserProfileRoute
authUserResetpasswordRoute: typeof authUserResetpasswordRoute
authUserSignupRoute: typeof authUserSignupRoute
logisticsLogisticsDeliveryScheduleRoute: typeof logisticsLogisticsDeliveryScheduleRoute
authUserIndexRoute: typeof authUserIndexRoute
}
declare module '@tanstack/react-router' {
@@ -290,6 +316,13 @@ declare module '@tanstack/react-router' {
preLoaderRoute: typeof mobileStuffMobileLayoutRouteRouteImport
parentRoute: typeof mobileStuffRoute
}
'/(auth)/user/': {
id: '/(auth)/user/'
path: '/user'
fullPath: '/user'
preLoaderRoute: typeof authUserIndexRouteImport
parentRoute: typeof rootRouteImport
}
'/_adminLayout/admin/settings': {
id: '/_adminLayout/admin/settings'
path: '/settings'
@@ -325,6 +358,13 @@ declare module '@tanstack/react-router' {
preLoaderRoute: typeof authUserResetpasswordRouteImport
parentRoute: typeof rootRouteImport
}
'/(auth)/user/profile': {
id: '/(auth)/user/profile'
path: '/user/profile'
fullPath: '/user/profile'
preLoaderRoute: typeof authUserProfileRouteImport
parentRoute: typeof rootRouteImport
}
'/_adminLayout/admin/_users': {
id: '/_adminLayout/admin/_users'
path: '/admin'
@@ -460,10 +500,12 @@ const rootRouteChildren: RootRouteChildren = {
AdminLayoutRouteRoute: AdminLayoutRouteRouteWithChildren,
mobileStuffRoute: mobileStuffRouteWithChildren,
authLoginRoute: authLoginRoute,
authUserProfileRoute: authUserProfileRoute,
authUserResetpasswordRoute: authUserResetpasswordRoute,
authUserSignupRoute: authUserSignupRoute,
logisticsLogisticsDeliveryScheduleRoute:
logisticsLogisticsDeliveryScheduleRoute,
authUserIndexRoute: authUserIndexRoute,
}
export const routeTree = rootRouteImport
._addFileChildren(rootRouteChildren)

View File

@@ -1,12 +1,5 @@
import { Link, useRouter, useSearch } from "@tanstack/react-router";
import {
getSession,
signin,
useAuth,
useUserRoles,
} from "../../../lib/authClient";
import { useAppForm } from "../../../lib/formStuff";
import { LstCard } from "../../../components/ui/lstCard";
import axios from "axios";
import { toast } from "sonner";
import {
CardContent,
@@ -14,12 +7,15 @@ import {
CardHeader,
CardTitle,
} from "../../../components/ui/card";
import { LstCard } from "../../../components/ui/lstCard";
import { getSession, useAuth, useUserRoles } from "../../../lib/authClient";
import { useAppForm } from "../../../lib/formStuff";
export default function LoginForm() {
const router = useRouter();
const search = useSearch({ from: "/(auth)/login" });
const username = localStorage.getItem("username") || "";
const rememeberMe = localStorage.getItem("rememberMe") === "true";
const rememberMe = localStorage.getItem("rememberMe") === "true";
const { setSession } = useAuth();
const { fetchRoles } = useUserRoles();
@@ -27,7 +23,7 @@ export default function LoginForm() {
defaultValues: {
username: username,
password: "",
rememberMe: rememeberMe,
rememberMe: rememberMe,
},
onSubmit: async ({ value }) => {
if (value.rememberMe) {
@@ -39,7 +35,7 @@ export default function LoginForm() {
}
try {
await signin({
await axios.post("/lst/api/user/login", {
username: value.username,
password: value.password,
});
@@ -50,14 +46,20 @@ export default function LoginForm() {
fetchRoles();
toast.success(
`Welcome back ${session?.user.name ? session?.user.name : session?.user.username} `
`Welcome back ${session?.user.name ? session?.user.name : session?.user.username} `,
);
router.invalidate();
router.history.push(search.redirect ? search.redirect : "/");
} catch (error) {
// @ts-ignore
if (!error.response.success) {
// @ts-ignore
toast.error(error.response.data.message);
} else {
// @ts-ignore
toast.error(error?.message);
}
}
},
});
return (
@@ -89,10 +91,7 @@ export default function LoginForm() {
<form.AppField
name="password"
children={(field) => (
<field.InputPasswordField
label="Password"
required={true}
/>
<field.InputPasswordField label="Password" required={true} />
)}
/>
<div className="flex flex-row justify-between mt-3 mb-3">
@@ -119,10 +118,7 @@ export default function LoginForm() {
<div className="mt-4 text-center text-sm">
Don&apos;t have an account?{" "}
<Link
to={"/user/signup"}
className="underline underline-offset-4"
>
<Link to={"/user/signup"} className="underline underline-offset-4">
Sign up
</Link>
</div>

View File

@@ -0,0 +1,13 @@
import { createFileRoute } from "@tanstack/react-router";
export const Route = createFileRoute("/(auth)/user/")({
component: RouteComponent,
});
function RouteComponent() {
return (
<div>
<span>Nothing here </span>
</div>
);
}

View File

@@ -0,0 +1,40 @@
import { createFileRoute, redirect } from "@tanstack/react-router";
import { authClient, useAuth } from "../../../lib/authClient";
export const Route = createFileRoute("/(auth)/user/profile")({
beforeLoad: async () => {
const result = await authClient.getSession({
query: { disableCookieCache: true }, // force DB/Server lookup
});
//console.log("session check:", result.data);
if (!result.data) {
throw redirect({
to: "/login",
search: {
redirect: location.pathname + location.search,
},
});
}
},
component: RouteComponent,
});
function RouteComponent() {
const { session } = useAuth();
return (
<div className="m-2">
<div>
<span>Things you can change</span>
<ol>
<li>Display name: {session?.user.displayUsername}</li>
<li>Name: {session?.user.name}</li>
<li>Image: To be added</li>
<li>password: **************</li>
</ol>
</div>
</div>
);
}

View File

@@ -1,10 +1,10 @@
import { defineConfig } from "vite";
import react from "@vitejs/plugin-react-swc";
import { tanstackRouter } from "@tanstack/router-plugin/vite";
import tailwindcss from "@tailwindcss/vite";
import path from "path";
import { tanstackRouter } from "@tanstack/router-plugin/vite";
import react from "@vitejs/plugin-react-swc";
import dotenv from "dotenv";
import path from "path";
import { fileURLToPath } from "url";
import { defineConfig } from "vite";
const __filename = fileURLToPath(import.meta.url);
const __dirname = path.dirname(__filename);
@@ -40,16 +40,12 @@ export default defineConfig({
allowedHosts: true,
proxy: {
"/lst/api": {
target: `http://localhost:${Number(
process.env.VITE_PORT || 4000
)}`,
target: `http://localhost:${Number(process.env.VITE_PORT || 4000)}`,
changeOrigin: true,
secure: false,
},
"/lst/ws": {
target: `ws://localhost:${Number(
process.env.VITE_PORT || 4000
)}`, // Your Go WebSocket endpoint
target: `ws://localhost:${Number(process.env.VITE_PORT || 4000)}`, // Your Go WebSocket endpoint
ws: true,
changeOrigin: true,
secure: false,

File diff suppressed because it is too large Load Diff

View File

@@ -34,6 +34,7 @@
"@tanstack/react-query": "^5.81.2",
"@tanstack/react-router": "^1.121.34",
"@tanstack/react-table": "^8.21.3",
"better-auth": "^1.3.28",
"class-variance-authority": "^0.7.1",
"clsx": "^2.1.1",
"date-fns": "^4.1.0",

View File

@@ -2,10 +2,14 @@ import {
ColumnDef,
flexRender,
getCoreRowModel,
useReactTable,
getPaginationRowModel,
getSortedRowModel,
useReactTable,
} from "@tanstack/react-table";
//import { Button } from "@/components/ui/button";
import { useState } from "react";
import { LstCard } from "@/components/extendedUI/LstCard";
import { ScrollArea } from "@/components/ui/scroll-area";
import {
Table,
TableBody,
@@ -14,10 +18,6 @@ import {
TableHeader,
TableRow,
} from "@/components/ui/table";
//import { Button } from "@/components/ui/button";
import { useState } from "react";
import { ScrollArea } from "@/components/ui/scroll-area";
import { LstCard } from "@/components/extendedUI/LstCard";
interface DataTableProps<TData, TValue> {
columns: ColumnDef<TData, TValue>[];
@@ -66,7 +66,7 @@ export function InvTable<TData, TValue>({
});
//console.log(table.getState().sorting);
//console.log(parseInt(style.height.replace("px", "")) - 50);
console.log(info);
// console.log(info);
return (
<LstCard
className="p-3"
@@ -80,9 +80,8 @@ export function InvTable<TData, TValue>({
<div>
<div className="flex flex-row justify-between">
<p className="text-center text-pretty">
{info.rowType} {data.length > 0 ? "lanes" : "lane"}{" "}
older than: {info.age}, {data.length} needing to be
completed
{info.rowType} {data.length > 0 ? "lanes" : "lane"} older than:{" "}
{info.age}, {data.length} needing to be completed
</p>
</div>
<ScrollArea className="h-72 rounded-md border m-2">
@@ -102,9 +101,8 @@ export function InvTable<TData, TValue>({
{header.isPlaceholder
? null
: flexRender(
header.column
.columnDef.header,
header.getContext()
header.column.columnDef.header,
header.getContext(),
)}
</TableHead>
);
@@ -117,15 +115,13 @@ export function InvTable<TData, TValue>({
table.getRowModel().rows.map((row) => (
<TableRow
key={row.id}
data-state={
row.getIsSelected() && "selected"
}
data-state={row.getIsSelected() && "selected"}
>
{row.getVisibleCells().map((cell) => (
<TableCell key={cell.id}>
{flexRender(
cell.column.columnDef.cell,
cell.getContext()
cell.getContext(),
)}
</TableCell>
))}

734
lstV2/package-lock.json generated

File diff suppressed because it is too large Load Diff

View File

@@ -68,6 +68,7 @@
"adm-zip": "^0.5.16",
"axios": "^1.10.0",
"bcryptjs": "^3.0.2",
"better-auth": "^1.3.28",
"croner": "^9.1.0",
"date-fns": "^4.1.0",
"date-fns-tz": "^3.2.0",

34
scripts/lstAppMoves.mjs Normal file
View File

@@ -0,0 +1,34 @@
import fs from "fs";
import path from "path";
const src_views = path.resolve("app/src/pkg/utils/mail/views");
const dest_views = path.resolve("dist/src/pkg/utils/mail/views");
const src_settings = path.resolve(
"app/src/internal/system/controller/settings/settings.json",
);
const dest_settings = path.resolve(
"dist/src/internal/system/controller/settings/settings.json",
);
// Delete old views if they exist
if (fs.existsSync(dest_views)) {
fs.rmSync(dest_views, { recursive: true, force: true });
}
// Delete old settings file if it exists
if (fs.existsSync(dest_settings)) {
fs.rmSync(dest_settings, { force: true }); // for single files we dont need the recursive
}
// Ensure the destination directory exists for settings.json
const dest_settings_dir = path.dirname(dest_settings);
if (!fs.existsSync(dest_settings_dir)) {
fs.mkdirSync(dest_settings_dir, { recursive: true });
}
// Copy files
fs.copyFileSync(src_settings, dest_settings);
fs.cpSync(src_views, dest_views, { recursive: true });
console.log(`All files copied`);