| sessionId |
|---|
| session-261005-185830-1pry |
The goal is to ensure that all generated API requests in the frontend application automatically and dynamically include the user’s Authorization: Bearer <token> header once authenticated upon login. Currently, the OpenAPI configuration in src/main.ts statically evaluates localStorage once at application startup using an inconsistent key, preventing subsequent API calls made after login from being authenticated. By configuring OpenAPI.TOKEN with a dynamic token resolver in src/main.ts and standardizing token persistence across authentication flows, all generated API service calls (e.g. ProposalService, AmendmentService, CommentService, AuthService) will seamlessly include the active bearer token.
src/main.ts to configure OpenAPI.TOKEN with a dynamic token resolver function using getAuthToken() or localStorage.BrandBar.vue, src/utils/auth.ts, and runtime configurations.openapi-typescript-codegen client) dynamically attach the Authorization: Bearer <token> header on every HTTP request whenever a token is present.gen-api.sh script (handled previously or independently).OpenAPI.TOKEN in src/main.ts as an asynchronous resolver function async () => getAuthToken() || '' (or () => getAuthToken() ?? undefined) so that resolve(options, config.TOKEN) evaluates per-request.src/generated/typescript/core/request.ts automatically attaches Authorization: Bearer <token> to request headers whenever token is non-empty.getAuthToken() from src/utils/auth.ts (which checks authToken and token fallbacks in localStorage).BrandBar.vue completes AuthService.loginFreighter, stored token in localStorage is immediately picked up by subsequent API requests without reloading the page.OpenAPI.TOKEN resolves to empty/undefined and requests are sent without Authorization header, preventing malformed headers or runtime errors.localStorage read per outgoing request.openapi-typescript-codegen generated core contracts.src/main.ts:
Currently sets static headers at module load time:
OpenAPI.BASE = ''
OpenAPI.HEADERS = localStorage.getItem("token") ? {"Authorization": "Bearer " + localStorage.getItem("token")} : {};
Issues:
OpenAPI.HEADERS is evaluated once when the bundle loads. If the user logs in afterwards, OpenAPI.HEADERS remains {}."token", while BrandBar.vue saves to "authToken".OpenAPI.TOKEN undefined, bypassing the built-in token resolver in request.ts.src/components/BrandBar.vue:
Upon connecting Freighter wallet:
const jwt = await AuthService.loginFreighter({stellarAddress: addr.address});
try {
localStorage.setItem("authToken", jwt.token as string);
} catch (_) {}
src/utils/auth.ts:
Provides helper functions:
export function getAuthToken(): string | null {
try {
return localStorage.getItem('authToken') || localStorage.getItem('token');
} catch {
return null;
}
}
src/generated/typescript/core/request.ts:
The generated client’s getHeaders() function natively supports dynamic token resolvers:
const [token, username, password, additionalHeaders] = await Promise.all([
resolve(options, config.TOKEN),
resolve(options, config.USERNAME),
resolve(options, config.PASSWORD),
resolve(options, config.HEADERS),
]);
...
if (isStringWithValue(token)) {
headers['Authorization'] = `Bearer ${token}`;
}
OpenAPI.TOKEN Resolver Function: Instead of assigning static headers or managing manual interceptors, leverage openapi-typescript-codegen's native TOKEN resolver OpenAPI.TOKEN = async () => getAuthToken() || ''. This ensures zero architectural changes to generated services and automatic per-request resolution.src/utils/auth.ts: Use getAuthToken() in src/main.ts to maintain unified support for both authToken and token storage keys and graceful exception handling if storage is restricted.OpenAPI.HEADERS static assignment and duplicate ./index.css import in src/main.ts.graph LR
User[User / Freighter Wallet] -->|Login| BrandBar[BrandBar.vue]
BrandBar -->|AuthService.loginFreighter| Backend[Backend API]
Backend -->|Return JWT Token| BrandBar
BrandBar -->|localStorage.setItem authToken| Storage[(localStorage)]
Services[Generated API Services\nProposal / Amendment / Comment] -->|__request| RequestCore[core/request.ts]
RequestCore -->|Resolve OpenAPI.TOKEN| AuthUtil[utils/auth.ts: getAuthToken]
AuthUtil -->|Read Token| Storage
RequestCore -->|Headers with Authorization: Bearer token| Backend
src/main.ts:
getAuthToken from ./utils/auth.OpenAPI.TOKEN = async () => getAuthToken() || '' (or () => getAuthToken() ?? undefined).OpenAPI.HEADERS static assignment.import './index.css'.src/utils/auth.ts:
getAuthToken() safely handles nulls and retrieves the active token.src/components/BrandBar.vue:
AuthService.loginFreighter is consistently saved to localStorage under authToken.src/main.ts (modified: configure OpenAPI.TOKEN resolver)src/components/BrandBar.vue (verified / modified: ensure consistent token persistence on login)src/utils/auth.ts (verified / modified: token utility resolution)getAuthToken() returns null safely without unhandled exceptions.request.ts will receive standard 401 response from backend, allowing frontend components to handle re-authentication.Verify that outgoing HTTP requests dispatched via generated API services include the Authorization: Bearer <token> header when authenticated, and omit it when unauthenticated.
BrandBar.vue.ProposalService.listProposals(), AmendmentService.listAmendments(), CommentService.addComment(), etc. include Authorization: Bearer <token> in the request headers.authToken already stored in localStorage, refresh the page.localStorage, verify that public API requests execute without an Authorization header and without JavaScript runtime errors.Authorization: Bearer headers.