@visns-studio/visns-components 6.6.4 → 6.15.0

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.
Files changed (97) hide show
  1. package/README.md +1623 -18
  2. package/package.json +10 -4
  3. package/src/components/DataGrid.jsx +171 -37
  4. package/src/components/Fetch.jsx +80 -3
  5. package/src/components/Form.jsx +9 -0
  6. package/src/components/Navigation.jsx +109 -50
  7. package/src/components/Notification.jsx +279 -9
  8. package/src/components/TableFilter.jsx +14 -1
  9. package/src/components/auth/AuthBrandPanel.jsx +43 -0
  10. package/src/components/auth/AuthLoading.jsx +78 -0
  11. package/src/components/auth/AuthShell.jsx +59 -0
  12. package/src/components/auth/ClientAuth.jsx +161 -0
  13. package/src/components/auth/ClientAuthFrame.jsx +59 -0
  14. package/src/components/auth/ClientLogin.jsx +266 -55
  15. package/src/components/auth/ClientOTPVerify.jsx +587 -115
  16. package/src/components/auth/ImpersonateGate.jsx +254 -0
  17. package/src/components/auth/Login.jsx +134 -41
  18. package/src/components/auth/LogoutScreen.jsx +112 -0
  19. package/src/components/auth/Reset.jsx +134 -77
  20. package/src/components/auth/TwoFactorAuth.jsx +475 -297
  21. package/src/components/auth/Verify.jsx +237 -126
  22. package/src/components/auth/authEndpoints.js +105 -0
  23. package/src/components/auth/authFont.js +23 -0
  24. package/src/components/auth/authHelpers.js +465 -0
  25. package/src/components/auth/clientAuthProtocols.js +240 -0
  26. package/src/components/auth/useOptionalRouter.js +49 -0
  27. package/src/components/callQueue/CallQueuePop.jsx +1502 -0
  28. package/src/components/callQueue/CallQueueSettings.jsx +508 -0
  29. package/src/components/callQueue/callQueueHelpers.js +280 -0
  30. package/src/components/callQueue/callQueueSettingsHelpers.js +75 -0
  31. package/src/components/columns/ColumnRenderers.jsx +53 -7
  32. package/src/components/generic/GenericAuth.jsx +163 -96
  33. package/src/components/generic/GenericDetail.jsx +215 -90
  34. package/src/components/generic/GenericIndex.jsx +20 -47
  35. package/src/components/generic/GenericMain.jsx +5 -0
  36. package/src/components/generic/GroupedReportRenderer.jsx +1 -5
  37. package/src/components/generic/StandardModal.jsx +17 -5
  38. package/src/components/generic/reportSemanticSteps/SemanticEntityStep.jsx +1 -6
  39. package/src/components/generic/reportSemanticSteps/SemanticFieldsStep.jsx +4 -11
  40. package/src/components/generic/reportSemanticSteps/SemanticFiltersStep.jsx +9 -27
  41. package/src/components/generic/reportSemanticSteps/SemanticGroupingStep.jsx +5 -13
  42. package/src/components/generic/reportSemanticSteps/SemanticParameterPrompt.jsx +5 -13
  43. package/src/components/generic/reportSemanticSteps/SemanticPreviewStep.jsx +14 -31
  44. package/src/components/generic/reportSemanticSteps/SemanticRelationsStep.jsx +3 -9
  45. package/src/components/generic/reportSemanticSteps/SemanticValueInput.jsx +2 -15
  46. package/src/components/navActive.js +60 -0
  47. package/src/components/notify/desktopNotifications.js +256 -0
  48. package/src/components/sketch/SketchField.jsx +12 -2
  49. package/src/components/sms/SmsComposeModal.jsx +495 -0
  50. package/src/components/sms/SmsInbox.jsx +596 -0
  51. package/src/components/sms/SmsInboxBadge.jsx +468 -0
  52. package/src/components/sms/SmsLineSettings.jsx +854 -0
  53. package/src/components/sms/SmsThreadPanel.jsx +1184 -0
  54. package/src/components/sms/smsEndpoints.js +56 -0
  55. package/src/components/sms/smsHelpers.js +1075 -0
  56. package/src/components/sms/smsLiveState.js +132 -0
  57. package/src/components/sms/useSmsLive.js +307 -0
  58. package/src/components/styles/CallQueuePop.module.scss +646 -0
  59. package/src/components/styles/CallQueueSettings.module.scss +460 -0
  60. package/src/components/styles/ClientAuth.module.scss +229 -0
  61. package/src/components/styles/GenericDetail.module.scss +153 -26
  62. package/src/components/styles/GenericIndex.module.scss +13 -0
  63. package/src/components/styles/GenericMain.module.scss +19 -2
  64. package/src/components/styles/ImpersonateGate.module.scss +85 -0
  65. package/src/components/styles/Login.module.scss +13 -122
  66. package/src/components/styles/LogoutScreen.module.scss +89 -0
  67. package/src/components/styles/Navigation.module.scss +509 -223
  68. package/src/components/styles/Notification.module.scss +103 -0
  69. package/src/components/styles/Reset.module.scss +52 -186
  70. package/src/components/styles/Sms.module.scss +2382 -0
  71. package/src/components/styles/TableFilter.module.scss +118 -98
  72. package/src/components/styles/TwoFactorAuth.module.scss +115 -176
  73. package/src/components/styles/Vault.module.scss +1983 -0
  74. package/src/components/styles/Verify.module.scss +57 -180
  75. package/src/components/styles/_authBrandPanel.scss +163 -0
  76. package/src/components/styles/_authShell.scss +369 -0
  77. package/src/components/utils/buildEnv.js +67 -0
  78. package/src/components/utils/displayValue.js +94 -0
  79. package/src/components/utils/useDensity.js +345 -9
  80. package/src/components/vault/OtpChip.jsx +208 -0
  81. package/src/components/vault/PasswordGenerator.jsx +145 -0
  82. package/src/components/vault/QrScanner.jsx +326 -0
  83. package/src/components/vault/VaultAccessLog.jsx +225 -0
  84. package/src/components/vault/VaultConfirmPanel.jsx +113 -0
  85. package/src/components/vault/VaultEntryForm.jsx +740 -0
  86. package/src/components/vault/VaultManager.jsx +1000 -0
  87. package/src/components/vault/VaultQuickSearch.jsx +681 -0
  88. package/src/components/vault/qrDecode.js +257 -0
  89. package/src/components/vault/useDebouncedValue.js +22 -0
  90. package/src/components/vault/useVaultReveal.js +160 -0
  91. package/src/components/vault/vaultClipboard.js +33 -0
  92. package/src/components/vault/vaultEndpoints.js +40 -0
  93. package/src/components/vault/vaultFit.js +116 -0
  94. package/src/components/vault/vaultHelpers.js +547 -0
  95. package/src/components/vault/vaultNavigation.jsx +58 -0
  96. package/src/components/vault/vaultOtp.js +105 -0
  97. package/src/index.js +233 -1
@@ -0,0 +1,105 @@
1
+ /**
2
+ * Asking the server for one 2FA code.
3
+ *
4
+ * Two places want the current code — the chip that ticks in the list's 2FA
5
+ * column, and the "copy 2FA" button in the row's actions — and they want the
6
+ * same request, the same defaults for a malformed response, and the same
7
+ * wording when it lands on the clipboard. That is all this module is.
8
+ *
9
+ * The code is never computed here. The shared secret stays on the server and
10
+ * the endpoint returns only the current code and how long it has left, so a
11
+ * compromised bundle leaks one 30-second code rather than a permanent seed.
12
+ *
13
+ * `request` is a parameter rather than an import so this file stays free of
14
+ * React and of the library's `Fetch` module: `node --test` drives it with a
15
+ * fake, and the two components pass `CustomFetch`.
16
+ */
17
+
18
+ /** What a TOTP period is when the server does not say. */
19
+ export const DEFAULT_OTP_PERIOD = 30;
20
+
21
+ /**
22
+ * The endpoint's payload, in the shape the components use.
23
+ *
24
+ * Defensive about every field: a proxy that returns an HTML error page with a
25
+ * 200 must leave the chip showing nothing rather than the string "undefined".
26
+ *
27
+ * @param {object} result `{code, expires_in, period}`
28
+ * @returns {{code: string, period: number, expiresIn: number}}
29
+ */
30
+ export const normaliseOtpResult = (result) => {
31
+ const code = String(result?.code ?? '');
32
+ const period = Number(result?.period);
33
+ const expiresIn = Number(result?.expires_in);
34
+
35
+ return {
36
+ code,
37
+ period: Number.isFinite(period) && period > 0 ? period : DEFAULT_OTP_PERIOD,
38
+ expiresIn: Number.isFinite(expiresIn) && expiresIn > 0 ? expiresIn : 0,
39
+ };
40
+ };
41
+
42
+ /**
43
+ * Fetch the current code for one entry.
44
+ *
45
+ * Resolves with `{code, period, expiresIn}` and rejects with whatever the
46
+ * request rejected with — the caller's `catch` is the "already reported by
47
+ * CustomFetch" path, so nothing here toasts.
48
+ *
49
+ * @param {Function} request CustomFetch, or anything with its signature.
50
+ * @param {object} routes resolved endpoints; only `otp` is read.
51
+ * @param {number|string} entryId
52
+ * @returns {Promise<{code: string, period: number, expiresIn: number}>}
53
+ */
54
+ export const fetchOtp = (request, routes, entryId) =>
55
+ new Promise((resolve, reject) => {
56
+ let settled = false;
57
+
58
+ const done = (result) => {
59
+ settled = true;
60
+ resolve(normaliseOtpResult(result));
61
+ };
62
+
63
+ let pending;
64
+
65
+ try {
66
+ pending = request(routes.otp(entryId), 'GET', {}, done, null);
67
+ } catch (error) {
68
+ reject(error);
69
+ return;
70
+ }
71
+
72
+ Promise.resolve(pending).then(
73
+ () => {
74
+ // A request that resolved without ever calling back has failed
75
+ // in a way the caller must still hear about, or a button sits
76
+ // spinning for the rest of the session.
77
+ if (!settled) {
78
+ reject(new Error('The 2FA endpoint returned no code.'));
79
+ }
80
+ },
81
+ (error) => {
82
+ if (!settled) reject(error);
83
+ }
84
+ );
85
+ });
86
+
87
+ /**
88
+ * What to tell the user once the code is on their clipboard.
89
+ *
90
+ * The remaining seconds are the point of the message: a TOTP copied with two
91
+ * seconds left is about to stop working, and the user is better off pressing
92
+ * the button again than pasting it.
93
+ *
94
+ * @param {number} expiresIn seconds the code has left, as the server counted.
95
+ * @returns {string}
96
+ */
97
+ export const otpCopiedMessage = (expiresIn) => {
98
+ const seconds = Math.floor(Number(expiresIn));
99
+
100
+ if (!Number.isFinite(seconds) || seconds <= 0) return '2FA code copied';
101
+
102
+ return `2FA code copied · valid for ${seconds}s`;
103
+ };
104
+
105
+ export default fetchOtp;
package/src/index.js CHANGED
@@ -7,7 +7,13 @@ import SortableList from './components/sorting/List';
7
7
  /** Utility Components */
8
8
  import { confirmDialog } from './components/utils/ConfirmDialog';
9
9
  import { showConfirmDialog } from './components/generic/ConfirmationDialog';
10
- import { useDensity, useAvailableHeight, DENSITY_GRID } from './components/utils/useDensity';
10
+ import {
11
+ useDensity,
12
+ useAvailableHeight,
13
+ DENSITY_GRID,
14
+ SECONDARY_GRID_HEIGHT,
15
+ } from './components/utils/useDensity';
16
+ import { readBuildEnv, buildEnv } from './components/utils/buildEnv';
11
17
 
12
18
  /** CRM Components */
13
19
  import AsyncSelect from './components/AsyncSelect';
@@ -48,10 +54,138 @@ import Login from './components/auth/Login';
48
54
  import Profile from './components/auth/Profile';
49
55
  import Reset from './components/auth/Reset';
50
56
  import Verify from './components/auth/Verify';
57
+ import TwoFactorAuth from './components/auth/TwoFactorAuth';
58
+ import AuthShell from './components/auth/AuthShell';
59
+ import AuthLoading from './components/auth/AuthLoading';
60
+ import AuthBrandPanel from './components/auth/AuthBrandPanel';
61
+ import ClientAuthFrame from './components/auth/ClientAuthFrame';
62
+ import ClientAuth from './components/auth/ClientAuth';
51
63
  import ClientLogin from './components/auth/ClientLogin';
52
64
  import ClientOTPVerify from './components/auth/ClientOTPVerify';
65
+ import ImpersonateGate from './components/auth/ImpersonateGate';
66
+ import LogoutScreen from './components/auth/LogoutScreen';
53
67
  import ClientPortal from './components/client/ClientPortal';
54
68
  import ClientDashboard from './components/client/ClientDashboard';
69
+ import {
70
+ DEFAULT_AUTH_ENDPOINTS,
71
+ DEFAULT_CLIENT_PATHS,
72
+ resolveAuthEndpoints,
73
+ resolveClientPaths,
74
+ } from './components/auth/authEndpoints';
75
+ import {
76
+ DEFAULT_CONTACT_HINTS,
77
+ applyUsernameDomain,
78
+ classifyContact,
79
+ clampOtp,
80
+ contactHint,
81
+ hasChallengeState,
82
+ isCompleteOtp,
83
+ isSuccessBody,
84
+ maskContact,
85
+ normaliseAuthError,
86
+ resendLabelFor,
87
+ syncCsrfFromResponse,
88
+ syncCsrfToken,
89
+ twoFactorSuccessTarget,
90
+ } from './components/auth/authHelpers';
91
+ import {
92
+ CLIENT_AUTH_PROTOCOLS,
93
+ DEFAULT_CLIENT_PROTOCOL,
94
+ resolveClientProtocol,
95
+ verifyContactFor,
96
+ } from './components/auth/clientAuthProtocols';
97
+
98
+ /** Call Queue Components */
99
+ import CallQueuePop from './components/callQueue/CallQueuePop';
100
+ import CallQueueSettings from './components/callQueue/CallQueueSettings';
101
+
102
+ // Vault — the staff password manager. VaultQuickSearch mounts through
103
+ // Navigation's `renderers` slot; VaultManager is the page behind it.
104
+ import OtpChip from './components/vault/OtpChip';
105
+ import VaultAccessLog from './components/vault/VaultAccessLog';
106
+ import VaultConfirmPanel from './components/vault/VaultConfirmPanel';
107
+ import VaultEntryForm from './components/vault/VaultEntryForm';
108
+ import VaultManager from './components/vault/VaultManager';
109
+ import VaultQuickSearch from './components/vault/VaultQuickSearch';
110
+ import PasswordGenerator from './components/vault/PasswordGenerator';
111
+ import QrScanner from './components/vault/QrScanner';
112
+ import useVaultReveal from './components/vault/useVaultReveal';
113
+ // The decoders are exported for a consumer that wants the QR paths somewhere
114
+ // else; `jsqr` itself stays behind the dynamic import inside them, so naming
115
+ // them here still costs a consumer nothing until one is called.
116
+ import {
117
+ decodeFromBlob,
118
+ decodeFromSource,
119
+ decodeImageData,
120
+ } from './components/vault/qrDecode';
121
+ import {
122
+ DEFAULT_ENDPOINTS as DEFAULT_VAULT_ENDPOINTS,
123
+ makeVaultEndpoints,
124
+ resolveVaultEndpoints,
125
+ } from './components/vault/vaultEndpoints';
126
+ import {
127
+ OTP_DEFAULTS,
128
+ cleanBase32,
129
+ describeOtpConfig,
130
+ formatOtp,
131
+ generatePassword,
132
+ hostFromUrl,
133
+ isValidBase32,
134
+ matchesShortcut,
135
+ openableUrl,
136
+ parseOtpAuthUri,
137
+ parseTags,
138
+ scorePassword,
139
+ secondsUntilBoundary,
140
+ shortcutLabel,
141
+ } from './components/vault/vaultHelpers';
142
+
143
+ // Messaging — the SMS inbox. SmsInboxBadge mounts through Navigation's
144
+ // `renderers` slot; SmsInbox is the page behind it, SmsThreadPanel is the
145
+ // conversation on its own for embedding elsewhere.
146
+ import SmsComposeModal from './components/sms/SmsComposeModal';
147
+ import SmsInbox from './components/sms/SmsInbox';
148
+ import SmsInboxBadge from './components/sms/SmsInboxBadge';
149
+ import SmsLineSettings from './components/sms/SmsLineSettings';
150
+ import SmsThreadPanel from './components/sms/SmsThreadPanel';
151
+ import useSmsLive from './components/sms/useSmsLive';
152
+ import {
153
+ DEFAULT_ENDPOINTS as DEFAULT_SMS_ENDPOINTS,
154
+ makeSmsEndpoints,
155
+ resolveSmsEndpoints,
156
+ } from './components/sms/smsEndpoints';
157
+ import {
158
+ MAX_SEGMENTS as SMS_MAX_SEGMENTS,
159
+ SMS_LIMITS,
160
+ STATUS_LABELS as SMS_STATUS_LABELS,
161
+ describeTransport,
162
+ fillTemplate,
163
+ groupMessagesByDay,
164
+ initialsFor,
165
+ isHeldTransport,
166
+ looksLikeNumber,
167
+ nextPlaceholder,
168
+ normaliseNumberForDisplay,
169
+ relativeTime,
170
+ segmentCount,
171
+ splitPersonName,
172
+ threadDisplayName,
173
+ toE164,
174
+ } from './components/sms/smsHelpers';
175
+
176
+ // Desktop alerts — the browser Notification API behind three gates (support,
177
+ // permission, the user's own switch). Used by the bell and the SMS badge; the
178
+ // module is exported so a consumer can drive it from anywhere else too.
179
+ import desktopNotifications, {
180
+ AUTO_CLOSE_MS as DESKTOP_ALERT_AUTO_CLOSE_MS,
181
+ STORAGE_KEY as DESKTOP_ALERTS_STORAGE_KEY,
182
+ getPermission as getDesktopPermission,
183
+ isEnabled as desktopAlertsEnabled,
184
+ isSupported as desktopAlertsSupported,
185
+ notify as desktopNotify,
186
+ requestPermission as requestDesktopPermission,
187
+ setEnabled as setDesktopAlertsEnabled,
188
+ } from './components/notify/desktopNotifications';
55
189
 
56
190
  /** CMS Generic Components */
57
191
  import CmsDetail from './components/generic/CmsDetail';
@@ -97,19 +231,85 @@ import DataSyncWizard from './components/oauth/DataSyncWizard';
97
231
 
98
232
 
99
233
  export {
234
+ applyUsernameDomain,
100
235
  AsyncSelect,
101
236
  AssociationManager,
102
237
  AudioPlayer,
238
+ AuthBrandPanel,
239
+ AuthLoading,
240
+ AuthShell,
103
241
  AuditLog,
104
242
  AuditLogs,
105
243
  Autocomplete,
106
244
  AutoRefreshControls,
107
245
  Breadcrumb,
246
+ buildEnv,
108
247
  BusinessCardOcr,
109
248
  Call,
249
+ CallQueuePop,
250
+ CallQueueSettings,
251
+ cleanBase32,
252
+ decodeFromBlob,
253
+ decodeFromSource,
254
+ decodeImageData,
255
+ DEFAULT_VAULT_ENDPOINTS,
256
+ describeOtpConfig,
257
+ formatOtp,
258
+ generatePassword,
259
+ hostFromUrl,
260
+ isValidBase32,
261
+ makeVaultEndpoints,
262
+ matchesShortcut,
263
+ openableUrl,
264
+ OTP_DEFAULTS,
265
+ OtpChip,
266
+ parseOtpAuthUri,
267
+ parseTags,
268
+ PasswordGenerator,
269
+ QrScanner,
270
+ resolveVaultEndpoints,
271
+ scorePassword,
272
+ secondsUntilBoundary,
273
+ shortcutLabel,
274
+ useVaultReveal,
275
+ VaultAccessLog,
276
+ VaultConfirmPanel,
277
+ VaultEntryForm,
278
+ VaultManager,
279
+ VaultQuickSearch,
280
+ DEFAULT_SMS_ENDPOINTS,
281
+ describeTransport,
282
+ fillTemplate,
283
+ groupMessagesByDay,
284
+ initialsFor,
285
+ isHeldTransport,
286
+ looksLikeNumber,
287
+ makeSmsEndpoints,
288
+ nextPlaceholder,
289
+ normaliseNumberForDisplay,
290
+ relativeTime,
291
+ resolveSmsEndpoints,
292
+ segmentCount,
293
+ splitPersonName,
294
+ SMS_LIMITS,
295
+ SMS_MAX_SEGMENTS,
296
+ SMS_STATUS_LABELS,
297
+ SmsComposeModal,
298
+ SmsInbox,
299
+ SmsInboxBadge,
300
+ SmsLineSettings,
301
+ SmsThreadPanel,
302
+ threadDisplayName,
303
+ toE164,
304
+ useSmsLive,
110
305
  CameraPlacement,
111
306
  CellWithTooltip,
307
+ clampOtp,
308
+ CLIENT_AUTH_PROTOCOLS,
309
+ classifyContact,
112
310
  ClientAssociationManager,
311
+ ClientAuth,
312
+ ClientAuthFrame,
113
313
  ClientLogin,
114
314
  ClientOTPVerify,
115
315
  ClientPortal,
@@ -118,10 +318,15 @@ export {
118
318
  CmsIndex,
119
319
  CmsSort,
120
320
  confirmDialog,
321
+ contactHint,
121
322
  CustomFetch,
122
323
  DataGrid,
123
324
  DataGridSearch,
124
325
  DatePickerPortal,
326
+ DEFAULT_AUTH_ENDPOINTS,
327
+ DEFAULT_CLIENT_PATHS,
328
+ DEFAULT_CLIENT_PROTOCOL,
329
+ DEFAULT_CONTACT_HINTS,
125
330
  DENSITY_GRID,
126
331
  Download,
127
332
  DropZone,
@@ -144,16 +349,32 @@ export {
144
349
  GenericReport,
145
350
  GenericSort,
146
351
  GroupedReportRenderer,
352
+ hasChallengeState,
353
+ ImpersonateGate,
147
354
  ImportWizardModal,
355
+ isCompleteOtp,
356
+ isSuccessBody,
148
357
  Loader,
149
358
  Login,
359
+ LogoutScreen,
360
+ maskContact,
150
361
  MergeEntity,
151
362
  MultiSelect,
152
363
  MultiCheckbox,
153
364
  NativeDateFilterEditor,
154
365
  Navigation,
366
+ normaliseAuthError,
155
367
  Notification,
156
368
  NotificationList,
369
+ desktopNotifications,
370
+ desktopAlertsEnabled,
371
+ desktopAlertsSupported,
372
+ desktopNotify,
373
+ DESKTOP_ALERT_AUTO_CLOSE_MS,
374
+ DESKTOP_ALERTS_STORAGE_KEY,
375
+ getDesktopPermission,
376
+ requestDesktopPermission,
377
+ setDesktopAlertsEnabled,
157
378
  DataSyncWizard,
158
379
  OAuthConnectionStatus,
159
380
  OAuthIntegrationsPage,
@@ -162,8 +383,13 @@ export {
162
383
  OcrTemplateEnhanced,
163
384
  Profile,
164
385
  ProposalTemplateSectionManager,
386
+ readBuildEnv,
165
387
  ProposalTemplatePreview,
166
388
  Reset,
389
+ resendLabelFor,
390
+ resolveAuthEndpoints,
391
+ resolveClientPaths,
392
+ resolveClientProtocol,
167
393
  SectionEditor,
168
394
  SectionGroupedReport,
169
395
  SectionTypeSelector,
@@ -173,10 +399,16 @@ export {
173
399
  SortableList,
174
400
  StagePopupModal,
175
401
  StandardModal,
402
+ syncCsrfFromResponse,
403
+ syncCsrfToken,
176
404
  Table,
177
405
  TableFilter,
406
+ TwoFactorAuth,
407
+ twoFactorSuccessTarget,
178
408
  useAvailableHeight,
179
409
  useDensity,
410
+ SECONDARY_GRID_HEIGHT,
180
411
  VariableInserter,
412
+ verifyContactFor,
181
413
  Verify,
182
414
  };