@controleonline/ui-common 1.2.79 → 1.2.80

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.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@controleonline/ui-common",
3
- "version": "1.2.79",
3
+ "version": "1.2.80",
4
4
  "author": "ControleOnline",
5
5
  "description": "ControleOnline Common Quasar UI Component",
6
6
  "license": "MIT",
@@ -0,0 +1,73 @@
1
+ /**
2
+ * Canonical password policy shared by create / change / reset flows.
3
+ * Must stay aligned with api-platform-users PasswordPolicyService.
4
+ */
5
+ export const PASSWORD_MIN_LENGTH = 6;
6
+
7
+ export const PASSWORD_MSG_REQUIRED = 'A senha é obrigatória.';
8
+ export const PASSWORD_MSG_MIN_LENGTH = `A senha precisa ter pelo menos ${PASSWORD_MIN_LENGTH} caracteres.`;
9
+ export const PASSWORD_MSG_COMPROMISED =
10
+ 'Esta senha não pode ser usada porque consta em lista de senhas comprometidas (vazamento de dados). Escolha outra senha.';
11
+ export const PASSWORD_MSG_CONFIRM_MISMATCH =
12
+ 'A senha e a confirmação devem ser iguais.';
13
+
14
+ export const PASSWORD_HELP_LINES = [
15
+ `Mínimo de ${PASSWORD_MIN_LENGTH} caracteres.`,
16
+ 'Não use senhas que já tenham vazado em vazamentos públicos de dados.',
17
+ ];
18
+
19
+ /**
20
+ * Client-side validation for length/required/confirm.
21
+ * Does not call breach API — that remains server-side.
22
+ * @returns {string|null} error message or null when valid
23
+ */
24
+ export function validatePasswordClient(password, confirm) {
25
+ const normalized = String(password ?? '').trim();
26
+ if (!normalized) {
27
+ return PASSWORD_MSG_REQUIRED;
28
+ }
29
+ if (normalized.length < PASSWORD_MIN_LENGTH) {
30
+ return PASSWORD_MSG_MIN_LENGTH;
31
+ }
32
+ if (confirm !== undefined && confirm !== null) {
33
+ const confirmNormalized = String(confirm ?? '').trim();
34
+ if (normalized !== confirmNormalized) {
35
+ return PASSWORD_MSG_CONFIRM_MISMATCH;
36
+ }
37
+ }
38
+ return null;
39
+ }
40
+
41
+ /**
42
+ * Map API / raw error text to product Portuguese copy for known policy violations.
43
+ */
44
+ export function mapPasswordErrorMessage(raw) {
45
+ const text = String(raw ?? '').trim();
46
+ if (!text) {
47
+ return text;
48
+ }
49
+ if (/leaked|data breach|compromised password|have i been pwned|comprometid/i.test(text)) {
50
+ return PASSWORD_MSG_COMPROMISED;
51
+ }
52
+ const minMatch =
53
+ text.match(/at least\s+(\d+)\s+characters/i) ||
54
+ text.match(/pelo menos\s+(\d+)\s+caracteres/i);
55
+ if (minMatch) {
56
+ return `A senha precisa ter pelo menos ${minMatch[1]} caracteres.`;
57
+ }
58
+ if (/must be identical|não coincidem|must match/i.test(text)) {
59
+ return PASSWORD_MSG_CONFIRM_MISMATCH;
60
+ }
61
+ return text;
62
+ }
63
+
64
+ export default {
65
+ PASSWORD_MIN_LENGTH,
66
+ PASSWORD_MSG_REQUIRED,
67
+ PASSWORD_MSG_MIN_LENGTH,
68
+ PASSWORD_MSG_COMPROMISED,
69
+ PASSWORD_MSG_CONFIRM_MISMATCH,
70
+ PASSWORD_HELP_LINES,
71
+ validatePasswordClient,
72
+ mapPasswordErrorMessage,
73
+ };
@@ -1,6 +1,6 @@
1
- import { getDeviceTypeLabel } from '@controleonline/ui-common/src/react/utils/printerDevices';
2
-
3
1
  const DEVICE_RUNTIME_FOOTER_TEXT_CONFIG_KEY = 'device-runtime-footer-text';
2
+ const PRINTER_DEVICE_TYPES = new Set(['PRINT', 'PRINTER']);
3
+ const IP_CAMERA_DEVICE_TYPE = 'IP_CAMERA';
4
4
 
5
5
  const safeTrim = value => String(value || '').trim();
6
6
 
@@ -25,6 +25,20 @@ const normalizeComparableText = value =>
25
25
  .normalize('NFD')
26
26
  .replace(/[\u0300-\u036f]/g, '');
27
27
 
28
+ const getRuntimeFooterDeviceTypeLabel = type => {
29
+ const normalizedType = safeTrim(type).toUpperCase();
30
+
31
+ if (PRINTER_DEVICE_TYPES.has(normalizedType)) {
32
+ return 'Impressora';
33
+ }
34
+
35
+ if (normalizedType === IP_CAMERA_DEVICE_TYPE) {
36
+ return 'Camera IP';
37
+ }
38
+
39
+ return normalizedType || 'DEVICE';
40
+ };
41
+
28
42
  const getRuntimeFooterTranslation = (store, type, key) =>
29
43
  safeTrim(globalThis?.t?.getMessageFromBuckets?.(store, type, key));
30
44
 
@@ -254,7 +268,7 @@ const getRuntimeFooterOperationalTypeLabel = ({device, deviceConfig} = {}) => {
254
268
  });
255
269
 
256
270
  return operationalTypeInfo.value
257
- ? getDeviceTypeLabel(operationalTypeInfo.value)
271
+ ? getRuntimeFooterDeviceTypeLabel(operationalTypeInfo.value)
258
272
  : '';
259
273
  };
260
274
 
@@ -382,7 +396,7 @@ const getRuntimeFooterDebugInfo = ({device, appVersion, deviceConfig}) => {
382
396
  deviceConfig,
383
397
  });
384
398
  const operationalTypeLabel = operationalTypeInfo.value
385
- ? getDeviceTypeLabel(operationalTypeInfo.value)
399
+ ? getRuntimeFooterDeviceTypeLabel(operationalTypeInfo.value)
386
400
  : '';
387
401
  const operationModeLabel =
388
402
  operationalTypeLabel === 'PDV'
@@ -1,5 +1,5 @@
1
1
  const assert = require('node:assert/strict')
2
- const {test} = global
2
+ const {test} = require('node:test')
3
3
 
4
4
  const {
5
5
  getImportErrorDetail,
@@ -1,10 +1,5 @@
1
1
  const assert = require('node:assert/strict')
2
- const {beforeAll, afterAll, test} = global
3
- const {jest} = require('@jest/globals')
4
-
5
- jest.mock('@controleonline/ui-common/src/react/utils/printerDevices', () => ({
6
- getDeviceTypeLabel: value => String(value || ''),
7
- }))
2
+ const {after, before, test} = require('node:test')
8
3
 
9
4
  const {
10
5
  getRuntimeFooterDebugInfo,
@@ -46,7 +41,7 @@ const restoreLocation = () => {
46
41
  delete globalThis.location
47
42
  }
48
43
 
49
- beforeAll(() => {
44
+ before(() => {
50
45
  global.t = {
51
46
  getMessageFromBuckets: (store, type, key) =>
52
47
  store === 'common' && type === 'option'
@@ -55,7 +50,7 @@ beforeAll(() => {
55
50
  }
56
51
  })
57
52
 
58
- afterAll(() => {
53
+ after(() => {
59
54
  global.t = originalTranslator
60
55
  })
61
56