Advertisement
minafaw3

customBaseQuery.ts

Feb 10th, 2025
20
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 3.33 KB | None | 0 0
  1. import { getToken } from 'ducks/Auth/selectors';
  2. import {
  3. getSelectedCompanyId,
  4. environmentSelector,
  5. regionSelector,
  6. apiKeySelector,
  7. SMApiUrlSelector,
  8. SMapiKeySelector,
  9. } from 'ducks/selectors';
  10. import {
  11. calculateSigningKey,
  12. buildCanonicalRequest,
  13. buildAuthorizationHeader,
  14. sha256Str,
  15. toHex,
  16. hmacSha256,
  17. } from './sigV4Utils';
  18.  
  19. export const customBaseQuery = async (
  20. {
  21. url, method, body, params = {},
  22. }: { url: string; method: 'GET' | 'POST' | 'PUT' | 'DELETE'; body?: any; params?: { pathParams?: Record<string, string>; queryParams?: Record<string, any> } },
  23. { getState }: { getState: () => any },
  24. ) => {
  25. const state = getState();
  26.  
  27. // Get configuration from state using your selectors
  28. const token = getToken(state);
  29. const companyId = getSelectedCompanyId(state);
  30. const region = regionSelector(state) || 'us-east-1';
  31. const SMApiUrl = SMApiUrlSelector(state);
  32. const SMapiKey = SMapiKeySelector(state);
  33.  
  34. // Prepare AWS credentials
  35. const accessKey = token?.Credentials?.AccessKeyId || '';
  36. const secretKey = token?.Credentials?.SecretKey || '';
  37. const sessionToken = token?.Credentials?.SessionToken;
  38. const service = 'execute-api';
  39. const baseURL = SMApiUrl;
  40.  
  41. // Replace path parameters in the URL.
  42. let resolvedUrl = url.replace(/{(\w+)}/g, (_, key) => (params.pathParams && params.pathParams[key] ? encodeURIComponent(params.pathParams[key]) : `{${key}}`));
  43. resolvedUrl = `${baseURL}${resolvedUrl}`;
  44.  
  45. // Handle query parameters
  46. const queryString = params.queryParams
  47. ? new URLSearchParams(params.queryParams).toString()
  48. : '';
  49. const fullUrl = queryString ? `${resolvedUrl}?${queryString}` : resolvedUrl;
  50.  
  51. // Prepare headers
  52. const headers: Record<string, string> = {
  53. 'Content-Type': 'application/json',
  54. Accept: 'application/json',
  55. ...(SMapiKey && { 'x-api-key': SMapiKey }),
  56. ...(sessionToken && { 'x-amz-security-token': sessionToken }),
  57. };
  58.  
  59. const datetime = new Date().toISOString().replace(/[:-]|\.\d{3}/g, '');
  60. const date = datetime.substring(0, 8);
  61. headers['x-amz-date'] = datetime;
  62.  
  63. const bodyString = body ? JSON.stringify(body) : '';
  64.  
  65. try {
  66. // Build canonical request
  67. const canonicalRequest = await buildCanonicalRequest(
  68. method.toUpperCase(),
  69. new URL(fullUrl).pathname,
  70. params.queryParams || {},
  71. headers,
  72. bodyString,
  73. );
  74.  
  75. const hashedCanonicalRequest = toHex(await sha256Str(canonicalRequest));
  76. const signingKey = await calculateSigningKey(secretKey, date, region, service);
  77. const stringToSign = [
  78. 'AWS4-HMAC-SHA256',
  79. datetime,
  80. `${date}/${region}/${service}/aws4_request`,
  81. hashedCanonicalRequest,
  82. ].join('\n');
  83. const signature = toHex(await hmacSha256(signingKey, stringToSign));
  84.  
  85. headers.Authorization = buildAuthorizationHeader(
  86. accessKey,
  87. `${date}/${region}/${service}/aws4_request`,
  88. headers,
  89. signature,
  90. );
  91.  
  92. const response = await fetch(fullUrl, {
  93. method: method.toUpperCase(),
  94. headers,
  95. body: bodyString,
  96. });
  97.  
  98. const data = await response.json().catch(() => ({}));
  99. return response.ok ? { data } : { error: { status: response.status, data } };
  100. } catch (error: any) {
  101. return { error: { status: 500, data: error.message } };
  102. }
  103. };
  104.  
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement