security: add helmet, rate limiting, webhook auth, fix token storage, restrict hard deletes
- Add helmet for HTTP security headers (CSP, HSTS, X-Frame-Options, etc.) - Add @nestjs/throttler for rate limiting (100 req/60s per IP) - Add shared secret validation on Signal webhook endpoint - Remove JWT token from localStorage, use Auth0 SDK memory cache with async getAccessTokenSilently() in API interceptor - Restrict hard delete (?hard=true) to ADMINISTRATOR role in service layer - Replace exposed Anthropic API key with placeholder in .env Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
This commit is contained in:
@@ -20,11 +20,22 @@ export const copilotApi = axios.create({
|
||||
timeout: 120000, // 2 minute timeout for AI requests
|
||||
});
|
||||
|
||||
// Shared request interceptor function
|
||||
const requestInterceptor = (config: any) => {
|
||||
const token = localStorage.getItem('auth0_token');
|
||||
if (token) {
|
||||
config.headers.Authorization = `Bearer ${token}`;
|
||||
// Token getter function - set by AuthContext when authenticated
|
||||
let getToken: (() => Promise<string>) | null = null;
|
||||
|
||||
export function setTokenGetter(getter: (() => Promise<string>) | null) {
|
||||
getToken = getter;
|
||||
}
|
||||
|
||||
// Shared request interceptor function (async to support token refresh)
|
||||
const requestInterceptor = async (config: any) => {
|
||||
if (getToken) {
|
||||
try {
|
||||
const token = await getToken();
|
||||
config.headers.Authorization = `Bearer ${token}`;
|
||||
} catch {
|
||||
// Token fetch failed - request goes without auth header
|
||||
}
|
||||
}
|
||||
|
||||
if (DEBUG_MODE) {
|
||||
@@ -69,7 +80,6 @@ const responseErrorInterceptor = (error: any) => {
|
||||
status: response.status,
|
||||
statusText: response.statusText,
|
||||
data: response.data,
|
||||
requestData: config?.data,
|
||||
}
|
||||
);
|
||||
|
||||
|
||||
Reference in New Issue
Block a user