@campxdev/campx-web-utils 2.1.1 → 2.1.3-alpha.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1 @@
1
+ export declare function generateClientToken(clientId: string, secret: string): string;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@campxdev/campx-web-utils",
3
- "version": "2.1.1",
3
+ "version": "2.1.3-alpha.1",
4
4
  "author": "CampX",
5
5
  "license": "MIT",
6
6
  "keywords": [
@@ -32,6 +32,7 @@
32
32
  "@hookform/resolvers": "^2.9.10",
33
33
  "axios": "^1.7.2",
34
34
  "cookie-js": "^0.0.1",
35
+ "crypto-js": "^4.2.0",
35
36
  "date-fns": "^4.1.0",
36
37
  "device-detector-js": "^3.0.3",
37
38
  "framer-motion": "^11.3.21",
@@ -73,6 +74,7 @@
73
74
  "@types/babel__template": "^7.4.4",
74
75
  "@types/babel__traverse": "^7.20.6",
75
76
  "@types/bonjour": "^3.5.13",
77
+ "@types/crypto-js": "^4.2.2",
76
78
  "@types/jest": "^27.0.1",
77
79
  "@types/js-cookie": "^3.0.2",
78
80
  "@types/lodash": "^4.17.5",
@@ -1,4 +1,11 @@
1
- import { Button, Dialog, RadioGroup, SingleSelect, Textarea, Typography } from '@campxdev/react-blueprint';
1
+ import {
2
+ Button,
3
+ Dialog,
4
+ RadioGroup,
5
+ SingleSelect,
6
+ Textarea,
7
+ Typography,
8
+ } from '@campxdev/react-blueprint';
2
9
  import { useState } from 'react';
3
10
  import { useMutation, useQueryClient } from 'react-query';
4
11
 
@@ -29,6 +36,10 @@ const NOT_CONNECTED_DISPOSITIONS = [
29
36
  { label: 'Not Answering', value: 'not_answering' },
30
37
  { label: 'Not Connected', value: 'not_connected' },
31
38
  { label: 'Fail to Call', value: 'fail_to_call' },
39
+ { label: 'Switched Off', value: 'switched_off' },
40
+ { label: 'Out of Service', value: 'out_of_service' },
41
+ { label: 'Invalid Number', value: 'invalid_number' },
42
+ { label: 'Number Busy', value: 'number_busy' },
32
43
  ];
33
44
 
34
45
  export interface DispositionFormData {
@@ -1,6 +1,7 @@
1
1
  import Axios from 'axios';
2
2
  import Cookies from 'js-cookie';
3
3
  import { ApplicationStore } from '../context/application-store';
4
+ import { generateClientToken } from '../utils/client-auth-token';
4
5
  import {
5
6
  institutionCode,
6
7
  isDevelopment,
@@ -77,6 +78,16 @@ axios.interceptors.request.use(
77
78
  config.headers.set('campx_open_payments_key', openPaymentsKey);
78
79
  }
79
80
 
81
+ // Inject client authentication token
82
+ const campxClientId = process.env.REACT_APP_CLIENT_ID;
83
+ const campxClientSecret = process.env.REACT_APP_CAMPX_CLIENT_SECRET;
84
+ if (campxClientId && campxClientSecret) {
85
+ config.headers.set(
86
+ 'x-campx-client',
87
+ generateClientToken(campxClientId, campxClientSecret),
88
+ );
89
+ }
90
+
80
91
  // Skip sending X-institution-code if the flag is set
81
92
  if (config.skipInstitutionCode) {
82
93
  config.headers.delete('x-institution-code');
@@ -1,6 +1,7 @@
1
1
  import Axios from 'axios';
2
2
  import Cookies from 'js-cookie';
3
3
  import { ApplicationStore } from '../context/application-store';
4
+ import { generateClientToken } from '../utils/client-auth-token';
4
5
  import { institutionCode, isDevelopment, tenantCode } from '../utils/constants';
5
6
 
6
7
  // Get base URL from environment variables
@@ -56,6 +57,16 @@ nonWorkspaceAxios.interceptors.request.use(
56
57
  config.headers.set('campx_open_payments_key', openPaymentsKey);
57
58
  }
58
59
 
60
+ // Inject client authentication token
61
+ const campxClientId = process.env.REACT_APP_CLIENT_ID;
62
+ const campxClientSecret = process.env.REACT_APP_CAMPX_CLIENT_SECRET;
63
+ if (campxClientId && campxClientSecret) {
64
+ config.headers.set(
65
+ 'x-campx-client',
66
+ generateClientToken(campxClientId, campxClientSecret),
67
+ );
68
+ }
69
+
59
70
  // Skip sending X-institution-code if the flag is set
60
71
  if (config.skipInstitutionCode) {
61
72
  config.headers.delete('x-institution-code');
@@ -0,0 +1,17 @@
1
+ import CryptoJS from 'crypto-js';
2
+
3
+ function toBase64Url(base64: string): string {
4
+ return base64.replace(/\+/g, '-').replace(/\//g, '_').replace(/=/g, '');
5
+ }
6
+
7
+ export function generateClientToken(clientId: string, secret: string): string {
8
+ const payload = { clientId, iat: Math.floor(Date.now() / 1000) };
9
+ const payloadBase64url = toBase64Url(btoa(JSON.stringify(payload)));
10
+
11
+ const signatureWordArray = CryptoJS.HmacSHA256(payloadBase64url, secret);
12
+ const signatureBase64url = toBase64Url(
13
+ CryptoJS.enc.Base64.stringify(signatureWordArray),
14
+ );
15
+
16
+ return `${payloadBase64url}.${signatureBase64url}`;
17
+ }