@autobusal/utilities 1.1.0 → 1.1.2
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/CHANGELOG.md +22 -0
- package/form.tsx +15 -2
- package/index.ts +5 -2
- package/package.json +6 -2
- package/sanitize.ts +11 -0
- package/users.tsx +24 -0
package/CHANGELOG.md
ADDED
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
# Changelog
|
|
2
|
+
|
|
3
|
+
All notable changes to this package are documented here. This project follows [Keep a Changelog](https://keepachangelog.com/) and [Semantic Versioning](https://semver.org/).
|
|
4
|
+
|
|
5
|
+
## [1.1.2] - 2026-07-24
|
|
6
|
+
|
|
7
|
+
### Added
|
|
8
|
+
|
|
9
|
+
- New `sanitizeHtml(html)` helper (wraps DOMPurify) for sanitizing admin-authored CMS content (pages, articles, notifications, policies, affiliate terms, document previews) before rendering via `dangerouslySetInnerHTML`. Added `dompurify` as a dependency.
|
|
10
|
+
|
|
11
|
+
## [1.1.1] - 2026-07-19
|
|
12
|
+
|
|
13
|
+
### Added
|
|
14
|
+
|
|
15
|
+
- `form.tsx`: the `Validate` helper now supports a cross-field `matches:<otherField>` rule (e.g. password confirmation). It accepts an optional third argument, react-hook-form's `getValues` (`UseFormGetValues<any>`), and emits a `validate` callback that compares the field against the named field, failing with the `errors.matches` message on mismatch. When `getValues` is not supplied the rule passes rather than blocking the form, so single-field rules keep working unchanged.
|
|
16
|
+
- `users.tsx` / `index.ts`: new `GetEnvironment(t)` helper exposing a payment-gateway `sandbox` / `production` mode selector (labels `admin_label.manage.environment.*`), following the same shape as `GetStatus`. It is now exported from the package index.
|
|
17
|
+
|
|
18
|
+
### Fixed
|
|
19
|
+
|
|
20
|
+
- `users.tsx`: `GetStatus` now returns all four real statuses. Previously it listed only Available (`1`) and Unavailable (`0`), so records whose actual status was Suspended (`2`) or Pending (`3`) had no matching `<option>`; the admin select silently fell back to Available and an unrelated save could overwrite the real status with Available. Added `suspended` and `pending` options to keep it in sync with `DisplayStatus`.
|
|
21
|
+
|
|
22
|
+
Authored by Ferjolt Ozuni. Consolidated from the magus and alvavel whitelabel patch sets into canonical @autobusal source (eliminates per-repo patch-package divergence).
|
package/form.tsx
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { TFunction } from 'i18next';
|
|
2
|
-
import { FieldError, Merge, FieldErrorsImpl } from 'react-hook-form';
|
|
2
|
+
import { FieldError, Merge, FieldErrorsImpl, UseFormGetValues } from 'react-hook-form';
|
|
3
3
|
import styled from 'styled-components';
|
|
4
4
|
|
|
5
5
|
interface ValidateType {
|
|
@@ -9,10 +9,14 @@ interface ValidateType {
|
|
|
9
9
|
minLength?: any
|
|
10
10
|
min?: any
|
|
11
11
|
max?: any
|
|
12
|
+
validate?: (value: any) => (boolean | string)
|
|
12
13
|
onChange?: (event?: any) => void
|
|
13
14
|
}
|
|
14
15
|
|
|
15
|
-
|
|
16
|
+
// `getValues` is only needed for cross-field rules (e.g. `matches:otherField`);
|
|
17
|
+
// pass react-hook-form's getValues from the calling component for those. Rules
|
|
18
|
+
// that don't reference another field work without it.
|
|
19
|
+
export const Validate = (rules: string, t: TFunction<'common'>, getValues?: UseFormGetValues<any>): ValidateType => {
|
|
16
20
|
const analyze = rules.split('|');
|
|
17
21
|
|
|
18
22
|
const validation: ValidateType = {};
|
|
@@ -25,6 +29,15 @@ export const Validate = (rules: string, t: TFunction<'common'>): ValidateType =>
|
|
|
25
29
|
validation.required = t('errors.required', { ns: 'common' });
|
|
26
30
|
break;
|
|
27
31
|
|
|
32
|
+
case 'matches':
|
|
33
|
+
// This field must equal another field (type[1] = the other field's name),
|
|
34
|
+
// e.g. password confirmation. Without getValues we can't compare, so we
|
|
35
|
+
// pass validation rather than blocking the form.
|
|
36
|
+
validation.validate = (value: any) => (
|
|
37
|
+
!getValues || value === getValues(type[1]) || t('errors.matches', { ns: 'common' })
|
|
38
|
+
);
|
|
39
|
+
break;
|
|
40
|
+
|
|
28
41
|
case 'email':
|
|
29
42
|
validation.pattern = {
|
|
30
43
|
value: /^[A-Z0-9._%+-]+@[A-Z0-9.-]+\.[A-Z]{2,}$/i,
|
package/index.ts
CHANGED
|
@@ -3,11 +3,13 @@ import { Validate, Display } from './form';
|
|
|
3
3
|
import { error, notify, success } from './notify';
|
|
4
4
|
import { getAllowed, getLanguages, getPayments } from './options';
|
|
5
5
|
import { getSex, getOptionsSex } from './passengers';
|
|
6
|
-
import { GetStatus, DisplayStatus } from './users';
|
|
6
|
+
import { GetStatus, GetEnvironment, DisplayStatus } from './users';
|
|
7
7
|
import { getRandomNumber } from './numbers';
|
|
8
8
|
import { getParams } from './manage';
|
|
9
|
+
import { sanitizeHtml } from './sanitize';
|
|
9
10
|
|
|
10
11
|
export {
|
|
12
|
+
sanitizeHtml,
|
|
11
13
|
Validate,
|
|
12
14
|
Display,
|
|
13
15
|
error,
|
|
@@ -26,5 +28,6 @@ export {
|
|
|
26
28
|
getOptionsSex,
|
|
27
29
|
getRandomNumber,
|
|
28
30
|
getSex,
|
|
29
|
-
GetStatus
|
|
31
|
+
GetStatus,
|
|
32
|
+
GetEnvironment
|
|
30
33
|
};
|
package/package.json
CHANGED
package/sanitize.ts
ADDED
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import DOMPurify from 'dompurify';
|
|
2
|
+
|
|
3
|
+
// Sanitizes admin-authored HTML (CMS pages, articles, notifications, policies,
|
|
4
|
+
// affiliate terms, document previews) before it's rendered via
|
|
5
|
+
// dangerouslySetInnerHTML. These fields are only writable by an admin-type
|
|
6
|
+
// account today, but rendering them unsanitized still means a compromised or
|
|
7
|
+
// phished admin can persist JS that runs in every visitor's and every other
|
|
8
|
+
// admin's browser - this is the defense-in-depth layer for that case.
|
|
9
|
+
export const sanitizeHtml = (html: string | null | undefined): string => (
|
|
10
|
+
DOMPurify.sanitize(html ?? '')
|
|
11
|
+
);
|
package/users.tsx
CHANGED
|
@@ -1,6 +1,11 @@
|
|
|
1
1
|
import { TFunction } from 'i18next';
|
|
2
2
|
import styled, { css } from 'styled-components';
|
|
3
3
|
|
|
4
|
+
// Kept in sync with DisplayStatus() below - the data model has 4 real
|
|
5
|
+
// states, so the admin select needs an <option> for every one of them.
|
|
6
|
+
// Without this, a record whose real status is Pending/Suspended had no
|
|
7
|
+
// matching option and the select silently fell back to showing (and, on
|
|
8
|
+
// an unrelated save, would silently overwrite the status with) Available.
|
|
4
9
|
export const GetStatus = (t: TFunction<'common'>) => ([
|
|
5
10
|
{
|
|
6
11
|
id: 1,
|
|
@@ -8,6 +13,25 @@ export const GetStatus = (t: TFunction<'common'>) => ([
|
|
|
8
13
|
}, {
|
|
9
14
|
id: 0,
|
|
10
15
|
name: t('data.statuses.unavailable', { ns: 'common' })
|
|
16
|
+
}, {
|
|
17
|
+
id: 2,
|
|
18
|
+
name: t('data.statuses.suspended', { ns: 'common' })
|
|
19
|
+
}, {
|
|
20
|
+
id: 3,
|
|
21
|
+
name: t('data.statuses.pending', { ns: 'common' })
|
|
22
|
+
}
|
|
23
|
+
]);
|
|
24
|
+
|
|
25
|
+
// Edited: Ferjolt Ozuni - Date: 2026-07-18
|
|
26
|
+
// Added: payment gateway sandbox/production mode selector, same pattern as
|
|
27
|
+
// GetStatus above.
|
|
28
|
+
export const GetEnvironment = (t: TFunction<'common'>) => ([
|
|
29
|
+
{
|
|
30
|
+
id: 'sandbox',
|
|
31
|
+
name: t('admin_label.manage.environment.sandbox', { ns: 'common' }),
|
|
32
|
+
}, {
|
|
33
|
+
id: 'production',
|
|
34
|
+
name: t('admin_label.manage.environment.production', { ns: 'common' })
|
|
11
35
|
}
|
|
12
36
|
]);
|
|
13
37
|
|