Preserve Zerodha callback state in frontend
This commit is contained in:
parent
ccaa363d48
commit
bc1ea376a4
@ -7,7 +7,7 @@
|
||||
"dev": "vite",
|
||||
"build": "vite build",
|
||||
"typecheck": "tsc --noEmit",
|
||||
"test": "npm run typecheck && tsx --test src/pages/admin/api.test.ts",
|
||||
"test": "npm run typecheck && tsx --test src/pages/admin/api.test.ts src/pages/zerodhaCallbackUtils.test.ts",
|
||||
"preview": "vite preview",
|
||||
"start": "vite --host 0.0.0.0 --port 3001"
|
||||
},
|
||||
|
||||
@ -3,28 +3,16 @@ import { Loader2 } from "lucide-react";
|
||||
import { Card, CardContent } from "@/components/ui/card";
|
||||
import { apiRequest } from "@/lib/queryClient";
|
||||
import PageEnter from "@/components/ui/page-enter";
|
||||
import {
|
||||
buildZerodhaBackendCallbackUrl,
|
||||
parseZerodhaCallbackParams,
|
||||
type ZerodhaCallbackParams,
|
||||
} from "./zerodhaCallbackUtils";
|
||||
|
||||
const CALLBACK_STORAGE_KEY = "zerodha:callback";
|
||||
const RETURN_PATH = "/portfolio";
|
||||
|
||||
type CallbackParams = {
|
||||
flow: string;
|
||||
status: string;
|
||||
requestToken: string;
|
||||
error: string;
|
||||
errorDescription: string;
|
||||
};
|
||||
|
||||
const parseParams = (): CallbackParams => {
|
||||
const params = new URLSearchParams(window.location.search);
|
||||
return {
|
||||
flow: (params.get("flow") || "").trim(),
|
||||
status: (params.get("status") || "").trim(),
|
||||
requestToken: (params.get("request_token") || "").trim(),
|
||||
error: (params.get("error") || params.get("error_type") || "").trim(),
|
||||
errorDescription: (params.get("error_description") || "").trim(),
|
||||
};
|
||||
};
|
||||
const parseParams = (): ZerodhaCallbackParams => parseZerodhaCallbackParams(window.location.search);
|
||||
|
||||
export default function ZerodhaCallback() {
|
||||
useEffect(() => {
|
||||
@ -50,9 +38,12 @@ export default function ZerodhaCallback() {
|
||||
return;
|
||||
}
|
||||
|
||||
const callbackPath =
|
||||
params.flow === "reconnect" ? "/broker/callback" : "/broker/zerodha/callback";
|
||||
const url = `${callbackPath}?request_token=${encodeURIComponent(params.requestToken)}`;
|
||||
if (!params.state) {
|
||||
finalize("error", "Missing callback state in the redirect URL.");
|
||||
return;
|
||||
}
|
||||
|
||||
const url = buildZerodhaBackendCallbackUrl(params);
|
||||
apiRequest("GET", url)
|
||||
.then(() => finalize("success"))
|
||||
.catch((err: any) => finalize("error", err?.message || "Unable to complete the login."));
|
||||
|
||||
43
src/pages/zerodhaCallbackUtils.test.ts
Normal file
43
src/pages/zerodhaCallbackUtils.test.ts
Normal file
@ -0,0 +1,43 @@
|
||||
import test from "node:test";
|
||||
import assert from "node:assert/strict";
|
||||
import {
|
||||
buildZerodhaBackendCallbackUrl,
|
||||
parseZerodhaCallbackParams,
|
||||
} from "./zerodhaCallbackUtils";
|
||||
|
||||
test("parseZerodhaCallbackParams reads state from callback query", () => {
|
||||
const parsed = parseZerodhaCallbackParams(
|
||||
"?request_token=req-123&state=state-456&status=success&flow=reconnect",
|
||||
);
|
||||
|
||||
assert.equal(parsed.requestToken, "req-123");
|
||||
assert.equal(parsed.state, "state-456");
|
||||
assert.equal(parsed.status, "success");
|
||||
assert.equal(parsed.flow, "reconnect");
|
||||
});
|
||||
|
||||
test("buildZerodhaBackendCallbackUrl forwards request token and state", () => {
|
||||
const url = buildZerodhaBackendCallbackUrl({
|
||||
flow: "connect",
|
||||
status: "success",
|
||||
requestToken: "req-123",
|
||||
state: "state-456",
|
||||
error: "",
|
||||
errorDescription: "",
|
||||
});
|
||||
|
||||
assert.equal(url, "/broker/zerodha/callback?request_token=req-123&state=state-456");
|
||||
});
|
||||
|
||||
test("buildZerodhaBackendCallbackUrl uses reconnect callback route", () => {
|
||||
const url = buildZerodhaBackendCallbackUrl({
|
||||
flow: "reconnect",
|
||||
status: "success",
|
||||
requestToken: "req-123",
|
||||
state: "state-456",
|
||||
error: "",
|
||||
errorDescription: "",
|
||||
});
|
||||
|
||||
assert.equal(url, "/broker/callback?request_token=req-123&state=state-456");
|
||||
});
|
||||
32
src/pages/zerodhaCallbackUtils.ts
Normal file
32
src/pages/zerodhaCallbackUtils.ts
Normal file
@ -0,0 +1,32 @@
|
||||
export type ZerodhaCallbackParams = {
|
||||
flow: string;
|
||||
status: string;
|
||||
requestToken: string;
|
||||
state: string;
|
||||
error: string;
|
||||
errorDescription: string;
|
||||
};
|
||||
|
||||
export function parseZerodhaCallbackParams(search: string): ZerodhaCallbackParams {
|
||||
const params = new URLSearchParams(search);
|
||||
return {
|
||||
flow: (params.get("flow") || "").trim(),
|
||||
status: (params.get("status") || "").trim(),
|
||||
requestToken: (params.get("request_token") || "").trim(),
|
||||
state: (params.get("state") || "").trim(),
|
||||
error: (params.get("error") || params.get("error_type") || "").trim(),
|
||||
errorDescription: (params.get("error_description") || "").trim(),
|
||||
};
|
||||
}
|
||||
|
||||
export function buildZerodhaBackendCallbackUrl(params: ZerodhaCallbackParams): string {
|
||||
const callbackPath = params.flow === "reconnect" ? "/broker/callback" : "/broker/zerodha/callback";
|
||||
const search = new URLSearchParams();
|
||||
if (params.requestToken) {
|
||||
search.set("request_token", params.requestToken);
|
||||
}
|
||||
if (params.state) {
|
||||
search.set("state", params.state);
|
||||
}
|
||||
return `${callbackPath}?${search.toString()}`;
|
||||
}
|
||||
Loading…
x
Reference in New Issue
Block a user