@micha.bigler/ui-core-micha 2.3.3 → 2.4.3

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.
@@ -20,14 +20,14 @@ jobs:
20
20
 
21
21
  steps:
22
22
  - name: Check out code
23
- uses: actions/checkout@v4
23
+ uses: actions/checkout@v6
24
24
  with:
25
25
  fetch-depth: 2
26
26
 
27
27
  - name: Set up Node
28
- uses: actions/setup-node@v4
28
+ uses: actions/setup-node@v6
29
29
  with:
30
- node-version: '20.x'
30
+ node-version: '24.15.0'
31
31
  registry-url: 'https://registry.npmjs.org'
32
32
 
33
33
  - name: Decide whether to publish
@@ -93,9 +93,9 @@ jobs:
93
93
 
94
94
  - name: Set up pnpm
95
95
  if: steps.version_check.outputs.should_publish == 'true'
96
- uses: pnpm/action-setup@v4
96
+ uses: pnpm/action-setup@v6
97
97
  with:
98
- version: 10.18.1
98
+ version: 11.1.2
99
99
 
100
100
  - name: Show version from package.json
101
101
  if: steps.version_check.outputs.should_publish == 'true'
@@ -412,7 +412,11 @@ export async function rejectRecoveryRequest(id, supportNote) {
412
412
  }
413
413
  export async function loginWithRecoveryPassword(email, password, token) {
414
414
  try {
415
- await apiClient.post(`/api/support/recovery-requests/recovery-login/${token}/`, {
415
+ // S50 (django-core-micha >=2.13.1): token wird im POST-Body übergeben,
416
+ // nicht mehr als URL-Path-Segment. Vermeidet Token-Leak in Referer-Headern,
417
+ // Server-Access-Logs und Browser-History (POST-Credentials-Exchange).
418
+ await apiClient.post('/api/support/recovery-requests/recovery-login/', {
419
+ token,
416
420
  email,
417
421
  password
418
422
  });
@@ -148,6 +148,29 @@ export async function startSocialLogin(provider, options = {}) {
148
148
  if (originUrl.hostname.startsWith('www.')) {
149
149
  originUrl.hostname = originUrl.hostname.slice(4);
150
150
  }
151
- const callbackUrl = options.callbackUrl || `${originUrl.origin}/login`;
151
+ // S62: Same-Origin-Validation für `callbackUrl`. Verhindert, dass künftige
152
+ // Konsumenten mit tainted Wert (z.B. `?next=https://evil.example/`) einen
153
+ // Open-Redirect via OAuth-Callback-Pfad erzeugen. Caller heute safe
154
+ // (`options.callbackUrl` wird nur intern gesetzt), aber defensive depth.
155
+ let callbackUrl = `${originUrl.origin}/login`;
156
+ if (options.callbackUrl) {
157
+ try {
158
+ const candidate = new URL(options.callbackUrl, window.location.origin);
159
+ if (candidate.origin === originUrl.origin) {
160
+ callbackUrl = candidate.toString();
161
+ }
162
+ else {
163
+ // Cross-origin → silent fallback auf Default; OAuth-Flows laufen
164
+ // weiter, nur ohne tainted URL. Symptom-Diagnose via Console-Warning.
165
+ // eslint-disable-next-line no-console
166
+ console.warn(`[startSocialLogin] callbackUrl cross-origin rejected: ${candidate.origin} != ${originUrl.origin}. Falling back to /login.`);
167
+ }
168
+ }
169
+ catch (_b) {
170
+ // Invalid URL → fallback, gleiche Rationale.
171
+ // eslint-disable-next-line no-console
172
+ console.warn('[startSocialLogin] callbackUrl is not a valid URL — falling back to /login.');
173
+ }
174
+ }
152
175
  submitSocialRedirectForm({ provider, callbackUrl, csrfToken, process });
153
176
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@micha.bigler/ui-core-micha",
3
- "version": "2.3.3",
3
+ "version": "2.4.3",
4
4
  "main": "dist/index.js",
5
5
  "module": "dist/index.js",
6
6
  "repository": {
@@ -9,25 +9,26 @@
9
9
  },
10
10
  "private": false,
11
11
  "peerDependencies": {
12
- "@emotion/react": "^11.0.0",
13
- "@emotion/styled": "^11.0.0",
14
- "@mui/material": "^7.3.5",
15
- "@mui/x-data-grid": "^8.4.0",
16
- "axios": "^1.0.0",
12
+ "@emotion/react": "^11.14.0",
13
+ "@emotion/styled": "^11.14.1",
14
+ "@mui/material": "^7.3.11",
15
+ "@mui/x-data-grid": "^8.28.6",
16
+ "axios": "^1.16.1",
17
+ "i18next": "^25.10.10 || ^26.0.0",
17
18
  "qrcode.react": "^4.2.0",
18
- "react": "^19.2.1",
19
- "react-dom": "^19.2.1",
20
- "react-helmet": "^6.0.0",
21
- "react-router-dom": "^7.9.6"
19
+ "react": "^19.2.6",
20
+ "react-dom": "^19.2.6",
21
+ "react-helmet": "^6.1.0",
22
+ "react-i18next": "^16.3.5 || ^17.0.0",
23
+ "react-router-dom": "^7.15.1"
22
24
  },
23
25
  "scripts": {
24
26
  "build": "tsc -p tsconfig.build.json"
25
27
  },
26
28
  "devDependencies": {
27
29
  "@mui/icons-material": "^7.3.11",
28
- "typescript": "^5.9.3"
29
- },
30
- "dependencies": {
31
- "react-i18next": "^16.3.5"
30
+ "i18next": "^26.2.0",
31
+ "react-i18next": "^17.0.8",
32
+ "typescript": "^6.0.3"
32
33
  }
33
34
  }
package/renovate.json ADDED
@@ -0,0 +1,10 @@
1
+ {
2
+ "$schema": "https://docs.renovatebot.com/renovate-schema.json",
3
+ "extends": [
4
+ "github>bigler-webapps/renovate-config",
5
+ "github>bigler-webapps/renovate-config:auto-merge"
6
+ ],
7
+ "baseBranchPatterns": [
8
+ "main"
9
+ ]
10
+ }
@@ -435,7 +435,11 @@ export async function rejectRecoveryRequest(id, supportNote) {
435
435
 
436
436
  export async function loginWithRecoveryPassword(email, password, token) {
437
437
  try {
438
- await apiClient.post(`/api/support/recovery-requests/recovery-login/${token}/`, {
438
+ // S50 (django-core-micha >=2.13.1): token wird im POST-Body übergeben,
439
+ // nicht mehr als URL-Path-Segment. Vermeidet Token-Leak in Referer-Headern,
440
+ // Server-Access-Logs und Browser-History (POST-Credentials-Exchange).
441
+ await apiClient.post('/api/support/recovery-requests/recovery-login/', {
442
+ token,
439
443
  email,
440
444
  password
441
445
  });
@@ -194,6 +194,30 @@ export async function startSocialLogin(provider, options = {}) {
194
194
  if (originUrl.hostname.startsWith('www.')) {
195
195
  originUrl.hostname = originUrl.hostname.slice(4);
196
196
  }
197
- const callbackUrl = options.callbackUrl || `${originUrl.origin}/login`;
197
+
198
+ // S62: Same-Origin-Validation für `callbackUrl`. Verhindert, dass künftige
199
+ // Konsumenten mit tainted Wert (z.B. `?next=https://evil.example/`) einen
200
+ // Open-Redirect via OAuth-Callback-Pfad erzeugen. Caller heute safe
201
+ // (`options.callbackUrl` wird nur intern gesetzt), aber defensive depth.
202
+ let callbackUrl = `${originUrl.origin}/login`;
203
+ if (options.callbackUrl) {
204
+ try {
205
+ const candidate = new URL(options.callbackUrl, window.location.origin);
206
+ if (candidate.origin === originUrl.origin) {
207
+ callbackUrl = candidate.toString();
208
+ } else {
209
+ // Cross-origin → silent fallback auf Default; OAuth-Flows laufen
210
+ // weiter, nur ohne tainted URL. Symptom-Diagnose via Console-Warning.
211
+ // eslint-disable-next-line no-console
212
+ console.warn(
213
+ `[startSocialLogin] callbackUrl cross-origin rejected: ${candidate.origin} != ${originUrl.origin}. Falling back to /login.`
214
+ );
215
+ }
216
+ } catch {
217
+ // Invalid URL → fallback, gleiche Rationale.
218
+ // eslint-disable-next-line no-console
219
+ console.warn('[startSocialLogin] callbackUrl is not a valid URL — falling back to /login.');
220
+ }
221
+ }
198
222
  submitSocialRedirectForm({ provider, callbackUrl, csrfToken, process });
199
223
  }
@@ -1,5 +1,6 @@
1
1
  {
2
2
  "compilerOptions": {
3
+ "rootDir": "./src",
3
4
  "outDir": "dist",
4
5
  "allowJs": true,
5
6
  "checkJs": false,
@@ -7,6 +8,7 @@
7
8
  "module": "ESNext",
8
9
  "target": "ES2017",
9
10
  "moduleResolution": "Node",
11
+ "ignoreDeprecations": "6.0",
10
12
  "esModuleInterop": true,
11
13
  "skipLibCheck": true,
12
14
  "noEmit": false,