Update password reset endpoint and add verification script

This commit is contained in:
NTumurbars 2025-09-18 16:40:49 +09:00
parent 143aad11d8
commit 4ef8a6057d
4 changed files with 138 additions and 3 deletions

View File

@ -0,0 +1,16 @@
export type PostCall = [path: string, options?: unknown];
export const postCalls: PostCall[] = [];
export const apiClient = {
POST: async (path: string, options?: unknown) => {
postCalls.push([path, options]);
return { data: null } as const;
},
GET: async () => ({ data: null } as const),
PUT: async () => ({ data: null } as const),
PATCH: async () => ({ data: null } as const),
DELETE: async () => ({ data: null } as const),
};
export const configureApiClientAuth = () => undefined;

View File

@ -0,0 +1,119 @@
#!/usr/bin/env node
const fs = require("node:fs");
const path = require("node:path");
const Module = require("node:module");
const ts = require("typescript");
const srcRoot = path.join(path.resolve(__dirname, ".."), "src");
const registerTsCompiler = extension => {
require.extensions[extension] = (module, filename) => {
const source = fs.readFileSync(filename, "utf8");
const { outputText } = ts.transpileModule(source, {
compilerOptions: {
module: ts.ModuleKind.CommonJS,
target: ts.ScriptTarget.ES2020,
jsx: ts.JsxEmit.ReactJSX,
esModuleInterop: true,
moduleResolution: ts.ModuleResolutionKind.NodeNext,
resolveJsonModule: true,
skipLibCheck: true,
},
fileName: filename,
});
module._compile(outputText, filename);
};
};
registerTsCompiler(".ts");
registerTsCompiler(".tsx");
const originalResolveFilename = Module._resolveFilename;
Module._resolveFilename = function resolve(request, parent, isMain, options) {
if (request === "@/core/api") {
const stubPath = path.resolve(__dirname, "stubs/core-api.ts");
return originalResolveFilename.call(this, stubPath, parent, isMain, options);
}
if (request.startsWith("@/")) {
const resolved = path.resolve(srcRoot, request.slice(2));
return originalResolveFilename.call(this, resolved, parent, isMain, options);
}
return originalResolveFilename.call(this, request, parent, isMain, options);
};
class LocalStorageMock {
constructor() {
this._store = new Map();
}
clear() {
this._store.clear();
}
getItem(key) {
return this._store.has(key) ? this._store.get(key) : null;
}
key(index) {
return Array.from(this._store.keys())[index] ?? null;
}
removeItem(key) {
this._store.delete(key);
}
setItem(key, value) {
this._store.set(key, String(value));
}
get length() {
return this._store.size;
}
}
global.localStorage = new LocalStorageMock();
const coreApiStub = require("./stubs/core-api.ts");
coreApiStub.postCalls.length = 0;
const { useAuthStore } = require("../src/features/auth/services/auth.store.ts");
(async () => {
try {
const payload = { email: "tester@example.com" };
await useAuthStore.getState().requestPasswordReset(payload);
if (coreApiStub.postCalls.length !== 1) {
throw new Error(`Expected 1 POST call, received ${coreApiStub.postCalls.length}`);
}
const [endpoint, options] = coreApiStub.postCalls[0];
if (endpoint !== "/auth/request-password-reset") {
throw new Error(`Expected endpoint \"/auth/request-password-reset\" but received \"${endpoint}\"`);
}
if (!options || typeof options !== "object") {
throw new Error("Password reset request did not include options payload");
}
const body = options.body;
if (!body || typeof body !== "object") {
throw new Error("Password reset request did not include a body");
}
if (body.email !== payload.email) {
throw new Error(
`Expected request body email to be \"${payload.email}\" but received \"${body.email}\"`
);
}
console.log("Password reset request forwarded correctly:", { endpoint, body });
} catch (error) {
console.error("Password reset request verification failed:", error);
process.exitCode = 1;
}
})();

View File

@ -53,8 +53,8 @@ export function useAuth() {
// Password reset request
const passwordResetMutation = useMutation({
mutationFn: (data: ForgotPasswordRequest) =>
apiClient.POST('/auth/forgot-password', { body: data }),
mutationFn: (data: ForgotPasswordRequest) =>
apiClient.POST('/auth/request-password-reset', { body: data }),
});
// Password reset

View File

@ -208,7 +208,7 @@ export const useAuthStore = create<AuthStoreState>()(
requestPasswordReset: async (data: ForgotPasswordRequest) => {
set({ loading: true, error: null });
try {
await apiClient.POST('/auth/forgot-password', { body: data });
await apiClient.POST('/auth/request-password-reset', { body: data });
set({ loading: false });
} catch (error) {
const authError = error as AuthError;