@sjolystinnovation/app-kit 0.7.0 → 0.8.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.
- package/README.md +19 -0
- package/package.json +9 -3
- package/src/validation/index.ts +2 -0
- package/src/validation/password.ts +37 -0
package/README.md
CHANGED
|
@@ -613,6 +613,24 @@ toast passes through, and so do the error states of `toast.promise`.
|
|
|
613
613
|
import { toast } from "@sjolystinnovation/app-kit/toast";
|
|
614
614
|
```
|
|
615
615
|
|
|
616
|
+
### `passwordSchema(strings?)`
|
|
617
|
+
|
|
618
|
+
From `@sjolystinnovation/app-kit/validation`. A zod schema for a new password, with the rules the APIs
|
|
619
|
+
enforce through ASP.NET Identity: at least 8 characters, with a lowercase letter, an uppercase letter
|
|
620
|
+
and a digit. No symbol is needed. Identity counts only ASCII, so the letters are A to Z and the digits
|
|
621
|
+
0 to 9, and "Å" does not count as uppercase. Identity sets no upper limit. An app whose API does adds
|
|
622
|
+
it with `.max()`. A failing password gets one issue per rule it breaks, each with its message from
|
|
623
|
+
`strings`. Missing messages fall back to `defaultPasswordStrings`, which are English.
|
|
624
|
+
|
|
625
|
+
```ts
|
|
626
|
+
import { passwordSchema } from "@sjolystinnovation/app-kit/validation";
|
|
627
|
+
|
|
628
|
+
const result = passwordSchema({ uppercase: "Ta med en stor bokstav fra A til Z." }).safeParse(newPassword);
|
|
629
|
+
const gargeRule = passwordSchema().max(128, "Be at most 128 characters long.");
|
|
630
|
+
```
|
|
631
|
+
|
|
632
|
+
`PASSWORD_MIN_LENGTH` holds the minimum, for hint text.
|
|
633
|
+
|
|
616
634
|
## Theming
|
|
617
635
|
|
|
618
636
|
The components draw every colour, corner radius and label size from theme variables with a light
|
|
@@ -680,6 +698,7 @@ with it and has to set the ones it uses itself.
|
|
|
680
698
|
|
|
681
699
|
- Next.js 16, React 19, next-auth 4.24 or later and axios 1.20 or later, as peer dependencies the
|
|
682
700
|
app installs itself.
|
|
701
|
+
- For `@sjolystinnovation/app-kit/validation`: zod 4, as an optional peer dependency.
|
|
683
702
|
- For `@sjolystinnovation/app-kit/toast`: sonner 2, as an optional peer dependency. Install a single
|
|
684
703
|
copy, because two copies keep two separate toast stores.
|
|
685
704
|
- `jsonwebtoken` comes with the package. `@sjolystinnovation/app-kit/auth` uses it on the server.
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@sjolystinnovation/app-kit",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.8.0",
|
|
4
4
|
"description": "Building blocks for Next.js apps that sign in against a JWT API through next-auth",
|
|
5
5
|
"license": "Apache-2.0",
|
|
6
6
|
"author": "Sjølyst Innovation AS",
|
|
@@ -24,6 +24,7 @@
|
|
|
24
24
|
"./server": "./src/server/index.ts",
|
|
25
25
|
"./ui": "./src/ui/index.ts",
|
|
26
26
|
"./toast": "./src/toast/index.ts",
|
|
27
|
+
"./validation": "./src/validation/index.ts",
|
|
27
28
|
"./styles.css": "./src/styles.css"
|
|
28
29
|
},
|
|
29
30
|
"files": [
|
|
@@ -44,11 +45,15 @@
|
|
|
44
45
|
"next-auth": "^4.24",
|
|
45
46
|
"react": "^19",
|
|
46
47
|
"react-dom": "^19",
|
|
47
|
-
"sonner": "^2"
|
|
48
|
+
"sonner": "^2",
|
|
49
|
+
"zod": "^4"
|
|
48
50
|
},
|
|
49
51
|
"peerDependenciesMeta": {
|
|
50
52
|
"sonner": {
|
|
51
53
|
"optional": true
|
|
54
|
+
},
|
|
55
|
+
"zod": {
|
|
56
|
+
"optional": true
|
|
52
57
|
}
|
|
53
58
|
},
|
|
54
59
|
"devDependencies": {
|
|
@@ -67,7 +72,8 @@
|
|
|
67
72
|
"react-dom": "^19.3.0",
|
|
68
73
|
"sonner": "^2.0.8",
|
|
69
74
|
"typescript": "^6.0.3",
|
|
70
|
-
"vitest": "^5.0.3"
|
|
75
|
+
"vitest": "^5.0.3",
|
|
76
|
+
"zod": "^4.6.5"
|
|
71
77
|
},
|
|
72
78
|
"keywords": [
|
|
73
79
|
"next.js",
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
import { z } from "zod";
|
|
2
|
+
import { withDefaults, type TextOverrides } from "../ui/withDefaults";
|
|
3
|
+
|
|
4
|
+
/** The fewest characters a password may have. */
|
|
5
|
+
export const PASSWORD_MIN_LENGTH = 8;
|
|
6
|
+
|
|
7
|
+
/** The message for each password rule that fails. */
|
|
8
|
+
export interface PasswordStrings {
|
|
9
|
+
tooShort: string;
|
|
10
|
+
lowercase: string;
|
|
11
|
+
uppercase: string;
|
|
12
|
+
digit: string;
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
export const defaultPasswordStrings: PasswordStrings = {
|
|
16
|
+
tooShort: `Use at least ${PASSWORD_MIN_LENGTH} characters.`,
|
|
17
|
+
lowercase: "Include a lowercase letter from a to z.",
|
|
18
|
+
uppercase: "Include an uppercase letter from A to Z.",
|
|
19
|
+
digit: "Include a digit from 0 to 9.",
|
|
20
|
+
};
|
|
21
|
+
|
|
22
|
+
/**
|
|
23
|
+
* A zod schema for a new password, with the rules the APIs enforce through ASP.NET Identity. Identity
|
|
24
|
+
* counts only ASCII letters and digits, so "Å" is neither an uppercase nor a lowercase letter here.
|
|
25
|
+
* Length counts UTF-16 code units, as Identity does. There is no upper limit, because Identity has
|
|
26
|
+
* none. An app whose API sets one adds it with `.max()`. A failing password gets one issue per rule
|
|
27
|
+
* it breaks.
|
|
28
|
+
*/
|
|
29
|
+
export function passwordSchema(strings?: TextOverrides<PasswordStrings>) {
|
|
30
|
+
const text = withDefaults(defaultPasswordStrings, strings);
|
|
31
|
+
return z
|
|
32
|
+
.string()
|
|
33
|
+
.min(PASSWORD_MIN_LENGTH, text.tooShort)
|
|
34
|
+
.regex(/[a-z]/, text.lowercase)
|
|
35
|
+
.regex(/[A-Z]/, text.uppercase)
|
|
36
|
+
.regex(/[0-9]/, text.digit);
|
|
37
|
+
}
|