diff --git a/.github/workflows/build.yaml b/.github/workflows/build.yaml index e69e59b0c..5301fdcd1 100644 --- a/.github/workflows/build.yaml +++ b/.github/workflows/build.yaml @@ -222,7 +222,7 @@ jobs: steps: - name: Docker meta id: meta - uses: docker/metadata-action@v5.6.1 + uses: docker/metadata-action@v5.7.0 with: images: "${{ env.IMAGE }}" bake-target: docker-metadata-action @@ -238,7 +238,7 @@ jobs: - name: Docker meta (debug variant) id: meta-debug - uses: docker/metadata-action@v5.6.1 + uses: docker/metadata-action@v5.7.0 with: images: "${{ env.IMAGE }}" bake-target: docker-metadata-action-debug @@ -255,7 +255,7 @@ jobs: - name: Docker meta (syn2mas) id: meta-syn2mas - uses: docker/metadata-action@v5.6.1 + uses: docker/metadata-action@v5.7.0 with: images: "${{ env.IMAGE_SYN2MAS }}" bake-target: docker-metadata-action-syn2mas @@ -273,7 +273,7 @@ jobs: uses: sigstore/cosign-installer@v3.8.1 - name: Set up Docker Buildx - uses: docker/setup-buildx-action@v3.9.0 + uses: docker/setup-buildx-action@v3.10.0 with: buildkitd-config-inline: | [registry."docker.io"] @@ -288,7 +288,7 @@ jobs: - name: Build and push id: bake - uses: docker/bake-action@v6.4.0 + uses: docker/bake-action@v6.5.0 with: files: | ./docker-bake.hcl diff --git a/.github/workflows/coverage.yaml b/.github/workflows/coverage.yaml index 2a6f50c94..06be3b84f 100644 --- a/.github/workflows/coverage.yaml +++ b/.github/workflows/coverage.yaml @@ -33,7 +33,7 @@ jobs: run: make coverage - name: Upload to codecov.io - uses: codecov/codecov-action@v5.3.1 + uses: codecov/codecov-action@v5.4.0 with: token: ${{ secrets.CODECOV_TOKEN }} files: policies/coverage.json @@ -60,7 +60,7 @@ jobs: run: npm run coverage - name: Upload to codecov.io - uses: codecov/codecov-action@v5.3.1 + uses: codecov/codecov-action@v5.4.0 with: token: ${{ secrets.CODECOV_TOKEN }} directory: frontend/coverage/ @@ -127,7 +127,7 @@ jobs: grcov . --binary-path ./target/debug/deps/ -s . -t lcov --branch --ignore-not-existing --ignore '../*' --ignore "/*" -o target/coverage/tests.lcov - name: Upload to codecov.io - uses: codecov/codecov-action@v5.3.1 + uses: codecov/codecov-action@v5.4.0 with: token: ${{ secrets.CODECOV_TOKEN }} files: target/coverage/*.lcov diff --git a/crates/policy/src/model.rs b/crates/policy/src/model.rs index aef4f3c08..4301b4165 100644 --- a/crates/policy/src/model.rs +++ b/crates/policy/src/model.rs @@ -32,6 +32,12 @@ pub enum Code { /// The username contains only numeric characters. UsernameAllNumeric, + /// The username is banned. + UsernameBanned, + + /// The username is not allowed. + UsernameNotAllowed, + /// The email domain is not allowed. EmailDomainNotAllowed, @@ -54,6 +60,8 @@ impl Code { Self::UsernameTooLong => "username-too-long", Self::UsernameInvalidChars => "username-invalid-chars", Self::UsernameAllNumeric => "username-all-numeric", + Self::UsernameBanned => "username-banned", + Self::UsernameNotAllowed => "username-not-allowed", Self::EmailDomainNotAllowed => "email-domain-not-allowed", Self::EmailDomainBanned => "email-domain-banned", Self::EmailNotAllowed => "email-not-allowed", diff --git a/docs/reference/configuration.md b/docs/reference/configuration.md index e69d14804..7289fec90 100644 --- a/docs/reference/configuration.md +++ b/docs/reference/configuration.md @@ -382,6 +382,35 @@ policy: # don't require clients to provide a client_uri. default: false allow_missing_client_uri: false + # Restrictions on user registration + registration: + # If specified, the username (localpart) *must* match one of the allowed + # usernames. If unspecified, all usernames are allowed. + allowed_usernames: + # Exact usernames that are allowed + literals: ["alice", "bob"] + # Substrings that match allowed usernames + substrings: ["user"] + # Regular expressions that match allowed usernames + regexes: ["^[a-z]+$"] + # Prefixes that match allowed usernames + prefixes: ["user-"] + # Suffixes that match allowed usernames + suffixes: ["-corp"] + # If specified, the username (localpart) *must not* match one of the + # banned usernames. If unspecified, all usernames are allowed. + banned_usernames: + # Exact usernames that are banned + literals: ["admin", "root"] + # Substrings that match banned usernames + substrings: ["admin", "root"] + # Regular expressions that match banned usernames + regexes: ["^admin$", "^root$"] + # Prefixes that match banned usernames + prefixes: ["admin-", "root-"] + # Suffixes that match banned usernames + suffixes: ["-admin", "-root"] + # Restrict what email addresses can be added to a user emails: # If specified, the email address *must* match one of the allowed addresses. diff --git a/frontend/package-lock.json b/frontend/package-lock.json index ae8e7f934..44e87338e 100644 --- a/frontend/package-lock.json +++ b/frontend/package-lock.json @@ -13,7 +13,7 @@ "@radix-ui/react-collapsible": "^1.1.3", "@radix-ui/react-dialog": "^1.1.6", "@tanstack/react-query": "^5.66.9", - "@tanstack/react-router": "^1.111.7", + "@tanstack/react-router": "^1.111.11", "@vector-im/compound-design-tokens": "4.0.0", "@vector-im/compound-web": "^7.6.4", "@zxcvbn-ts/core": "^3.0.4", @@ -24,7 +24,7 @@ "react": "^19.0.0", "react-dom": "^19.0.0", "react-i18next": "^15.4.1", - "swagger-ui-dist": "^5.19.0", + "swagger-ui-dist": "^5.20.0", "valibot": "^1.0.0-rc.2", "vaul": "^1.1.2" }, @@ -37,14 +37,14 @@ "@graphql-codegen/cli": "^5.0.5", "@graphql-codegen/client-preset": "^4.6.4", "@graphql-codegen/typescript-msw": "^3.0.0", - "@storybook/addon-essentials": "^8.6.0", - "@storybook/addon-interactions": "^8.6.0", - "@storybook/react": "^8.6.0", - "@storybook/react-vite": "^8.6.0", + "@storybook/addon-essentials": "^8.6.2", + "@storybook/addon-interactions": "^8.6.2", + "@storybook/react": "^8.6.2", + "@storybook/react-vite": "^8.6.2", "@storybook/test": "^8.5.5", "@tanstack/react-query-devtools": "^5.66.9", - "@tanstack/router-devtools": "^1.111.7", - "@tanstack/router-vite-plugin": "^1.111.7", + "@tanstack/router-devtools": "^1.111.11", + "@tanstack/router-vite-plugin": "^1.111.12", "@testing-library/jest-dom": "^6.6.3", "@testing-library/react": "^16.2.0", "@testing-library/user-event": "^14.6.1", @@ -4735,9 +4735,9 @@ } }, "node_modules/@storybook/addon-actions": { - "version": "8.6.0", - "resolved": "https://registry.npmjs.org/@storybook/addon-actions/-/addon-actions-8.6.0.tgz", - "integrity": "sha512-lI03stcI28wN8trjp7zx0PzN1NRxSpU/551slzEhSM0tghcLxcfLZR/wh4Jp0T68Obj7z//YXPttZ9PBFajs6w==", + "version": "8.6.2", + "resolved": "https://registry.npmjs.org/@storybook/addon-actions/-/addon-actions-8.6.2.tgz", + "integrity": "sha512-grIRReMObwwt/VZemFnaKDbeaiK257egN+/knuqMbT3eUA6aitlzTr5UynBZnsVYbJFdD6PYyIZMKoGWEdFJlQ==", "dev": true, "license": "MIT", "dependencies": { @@ -4752,13 +4752,13 @@ "url": "https://opencollective.com/storybook" }, "peerDependencies": { - "storybook": "^8.6.0" + "storybook": "^8.6.2" } }, "node_modules/@storybook/addon-backgrounds": { - "version": "8.6.0", - "resolved": "https://registry.npmjs.org/@storybook/addon-backgrounds/-/addon-backgrounds-8.6.0.tgz", - "integrity": "sha512-MbMPjuC19jJBXqQext8rENBACLKujDn+MuxIbNYMmn2ljzeYFp87tVxzlCB7XY7rV0zvkHxH8N/zDnPl7pBTcQ==", + "version": "8.6.2", + "resolved": "https://registry.npmjs.org/@storybook/addon-backgrounds/-/addon-backgrounds-8.6.2.tgz", + "integrity": "sha512-xysLkeHCdwh1xcLIrarRnJipl2ccoR1Oy6hHYcPtFiUB89gd6DsTe2WC8zsqrO16ogPYovCTP4UiBzApo+yoYA==", "dev": true, "license": "MIT", "dependencies": { @@ -4771,13 +4771,13 @@ "url": "https://opencollective.com/storybook" }, "peerDependencies": { - "storybook": "^8.6.0" + "storybook": "^8.6.2" } }, "node_modules/@storybook/addon-controls": { - "version": "8.6.0", - "resolved": "https://registry.npmjs.org/@storybook/addon-controls/-/addon-controls-8.6.0.tgz", - "integrity": "sha512-oc+mssxmNY+D26jyJ+IZ1u8bmzveCO2wqpUl6vtLM5MruchZAHzHqa2ZIn+H9KOEqcKlYVDF5n6oEuprcnrsdg==", + "version": "8.6.2", + "resolved": "https://registry.npmjs.org/@storybook/addon-controls/-/addon-controls-8.6.2.tgz", + "integrity": "sha512-MOTzQTZ64Wfc/hWBflnrOsw8qdNSu37VFzvcXtQa1npEJUO6KU822KvvuKGtdDZJhwcVrGDM5yL9gy4Nw5/M5g==", "dev": true, "license": "MIT", "dependencies": { @@ -4790,20 +4790,20 @@ "url": "https://opencollective.com/storybook" }, "peerDependencies": { - "storybook": "^8.6.0" + "storybook": "^8.6.2" } }, "node_modules/@storybook/addon-docs": { - "version": "8.6.0", - "resolved": "https://registry.npmjs.org/@storybook/addon-docs/-/addon-docs-8.6.0.tgz", - "integrity": "sha512-ytYn5ec2Tp62t9emjXgm4Ds+eG7SiSg/vNeOwM6L1lM2UCV2/XdzntbqlUb/FHehSXIv9eRJDSe5BBzPieUUaw==", + "version": "8.6.2", + "resolved": "https://registry.npmjs.org/@storybook/addon-docs/-/addon-docs-8.6.2.tgz", + "integrity": "sha512-urc6GCKZRV2Mhh2V0fzhkqOdKYvJ1E45dCeCZ7hNrz0Yfe72NG8rTz5U/+u7ESUMTjE4Q5sAgplW7hnELt4vLg==", "dev": true, "license": "MIT", "dependencies": { "@mdx-js/react": "^3.0.0", - "@storybook/blocks": "8.6.0", - "@storybook/csf-plugin": "8.6.0", - "@storybook/react-dom-shim": "8.6.0", + "@storybook/blocks": "8.6.2", + "@storybook/csf-plugin": "8.6.2", + "@storybook/react-dom-shim": "8.6.2", "react": "^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0", "react-dom": "^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0", "ts-dedent": "^2.0.0" @@ -4813,25 +4813,25 @@ "url": "https://opencollective.com/storybook" }, "peerDependencies": { - "storybook": "^8.6.0" + "storybook": "^8.6.2" } }, "node_modules/@storybook/addon-essentials": { - "version": "8.6.0", - "resolved": "https://registry.npmjs.org/@storybook/addon-essentials/-/addon-essentials-8.6.0.tgz", - "integrity": "sha512-T3R9Q1hq6eJKy758gQgYEuAYxcddGZ8eGBLIyIJEgzpwsUnN5mF+rIqx8LoWxpWu/xiKzg17LqCBnJbLGkRZUA==", + "version": "8.6.2", + "resolved": "https://registry.npmjs.org/@storybook/addon-essentials/-/addon-essentials-8.6.2.tgz", + "integrity": "sha512-nJvtVVcB8847Olsd5vbnW34SVQpboXdSGPRuUNTeRXOAIQQc5heWwRXjgBQgqF2kD5GaPaHfKTfec37cVyJFfA==", "dev": true, "license": "MIT", "dependencies": { - "@storybook/addon-actions": "8.6.0", - "@storybook/addon-backgrounds": "8.6.0", - "@storybook/addon-controls": "8.6.0", - "@storybook/addon-docs": "8.6.0", - "@storybook/addon-highlight": "8.6.0", - "@storybook/addon-measure": "8.6.0", - "@storybook/addon-outline": "8.6.0", - "@storybook/addon-toolbars": "8.6.0", - "@storybook/addon-viewport": "8.6.0", + "@storybook/addon-actions": "8.6.2", + "@storybook/addon-backgrounds": "8.6.2", + "@storybook/addon-controls": "8.6.2", + "@storybook/addon-docs": "8.6.2", + "@storybook/addon-highlight": "8.6.2", + "@storybook/addon-measure": "8.6.2", + "@storybook/addon-outline": "8.6.2", + "@storybook/addon-toolbars": "8.6.2", + "@storybook/addon-viewport": "8.6.2", "ts-dedent": "^2.0.0" }, "funding": { @@ -4839,13 +4839,13 @@ "url": "https://opencollective.com/storybook" }, "peerDependencies": { - "storybook": "^8.6.0" + "storybook": "^8.6.2" } }, "node_modules/@storybook/addon-highlight": { - "version": "8.6.0", - "resolved": "https://registry.npmjs.org/@storybook/addon-highlight/-/addon-highlight-8.6.0.tgz", - "integrity": "sha512-xgSUzNV8ZpNDJ35bLz7wfg/q7/O/C5845wbZsn+PobUOWpOMOKeZwbGkO3Fh4+CWKeFuMhUpFiZSWkNgT+bV0g==", + "version": "8.6.2", + "resolved": "https://registry.npmjs.org/@storybook/addon-highlight/-/addon-highlight-8.6.2.tgz", + "integrity": "sha512-TtRW+JK1NNuRI6zEXQAHImqVW7x+wkFGddhE6ikWX6eXJER+dgXaPd1pGBNlEQp2kzdWbzOEvXbrIKU1cy1A7Q==", "dev": true, "license": "MIT", "dependencies": { @@ -4856,19 +4856,19 @@ "url": "https://opencollective.com/storybook" }, "peerDependencies": { - "storybook": "^8.6.0" + "storybook": "^8.6.2" } }, "node_modules/@storybook/addon-interactions": { - "version": "8.6.0", - "resolved": "https://registry.npmjs.org/@storybook/addon-interactions/-/addon-interactions-8.6.0.tgz", - "integrity": "sha512-AgobFrUxmKgGHKeOismuLZdXlndP3ZDquHztiomfMiu01xOqNPxG0+xoCcegvftU7hKE+TlBRzhjCWg/bFz4LQ==", + "version": "8.6.2", + "resolved": "https://registry.npmjs.org/@storybook/addon-interactions/-/addon-interactions-8.6.2.tgz", + "integrity": "sha512-9wv3TX9eupJfzubKbt6f9Z+VtrL6VOIkEKBJN/wifnHBgTHM3DsizerZX/7YKHdFbz6eJFr6efvaSWQ8CIvTNA==", "dev": true, "license": "MIT", "dependencies": { "@storybook/global": "^5.0.0", - "@storybook/instrumenter": "8.6.0", - "@storybook/test": "8.6.0", + "@storybook/instrumenter": "8.6.2", + "@storybook/test": "8.6.2", "polished": "^4.2.2", "ts-dedent": "^2.2.0" }, @@ -4877,13 +4877,13 @@ "url": "https://opencollective.com/storybook" }, "peerDependencies": { - "storybook": "^8.6.0" + "storybook": "^8.6.2" } }, "node_modules/@storybook/addon-measure": { - "version": "8.6.0", - "resolved": "https://registry.npmjs.org/@storybook/addon-measure/-/addon-measure-8.6.0.tgz", - "integrity": "sha512-ogc+VNLyXq8hGfI4Fkmh9i3JbxfiIViiINdBoldD6K0gId3yaqqrSwQ2vWhYIbfUuz+PsMxsoNS7MD4EiRXhPg==", + "version": "8.6.2", + "resolved": "https://registry.npmjs.org/@storybook/addon-measure/-/addon-measure-8.6.2.tgz", + "integrity": "sha512-qNzR8yj/g2FRRLBwTreGqeUR5ZcXpkhcdndWlf5rnxp97BDbPnGNCvaI9vhHS3GbjZ+C1FE+yG3o70O5Rhh7Ag==", "dev": true, "license": "MIT", "dependencies": { @@ -4895,13 +4895,13 @@ "url": "https://opencollective.com/storybook" }, "peerDependencies": { - "storybook": "^8.6.0" + "storybook": "^8.6.2" } }, "node_modules/@storybook/addon-outline": { - "version": "8.6.0", - "resolved": "https://registry.npmjs.org/@storybook/addon-outline/-/addon-outline-8.6.0.tgz", - "integrity": "sha512-IWxrNNZOk5rtOdnLNyK7gpqi0g0rMGYl5ju37Glbfa7iG2J1VKofG2CbkUpVyVY0uiTXqkKkhOKlc9zELhLQSg==", + "version": "8.6.2", + "resolved": "https://registry.npmjs.org/@storybook/addon-outline/-/addon-outline-8.6.2.tgz", + "integrity": "sha512-lgDCOkOLoehat4APUbKpAA7CBwXtxrRRK91hNBI3prUUBex6ML9jXWcuTDsGTrkilRkLOT7kN6H0DGj5rH/H9Q==", "dev": true, "license": "MIT", "dependencies": { @@ -4913,13 +4913,13 @@ "url": "https://opencollective.com/storybook" }, "peerDependencies": { - "storybook": "^8.6.0" + "storybook": "^8.6.2" } }, "node_modules/@storybook/addon-toolbars": { - "version": "8.6.0", - "resolved": "https://registry.npmjs.org/@storybook/addon-toolbars/-/addon-toolbars-8.6.0.tgz", - "integrity": "sha512-Mg0V9RrnDt/IQe+zjggGS+4Otkv4YFqyjL/ygwnV6aKGgzL5zFpC+5rf8MeBEvNeol9+THC/XltN/Xf+jbtLEQ==", + "version": "8.6.2", + "resolved": "https://registry.npmjs.org/@storybook/addon-toolbars/-/addon-toolbars-8.6.2.tgz", + "integrity": "sha512-rfUSMacIfGwPoYYeVro+3I5C3qNy0MgB+qJ16ejuTLTlx4ji0icAOckILmPmhIT577KqIQBo1R2sB+oMVzK9+w==", "dev": true, "license": "MIT", "funding": { @@ -4927,13 +4927,13 @@ "url": "https://opencollective.com/storybook" }, "peerDependencies": { - "storybook": "^8.6.0" + "storybook": "^8.6.2" } }, "node_modules/@storybook/addon-viewport": { - "version": "8.6.0", - "resolved": "https://registry.npmjs.org/@storybook/addon-viewport/-/addon-viewport-8.6.0.tgz", - "integrity": "sha512-sVDF3gIjGdvfBdCM/jEBu6Nd5GlqITKBtdySiQdNDl5JI4ak77ZM+T+VQmJxB4sIqvCjWzCbQqUC45nymVObug==", + "version": "8.6.2", + "resolved": "https://registry.npmjs.org/@storybook/addon-viewport/-/addon-viewport-8.6.2.tgz", + "integrity": "sha512-znUIG808UEEfF5Gg+T478ixblBwEebeOYaKLD7yfxKwL2TMTmaIq4DXPESqV9M1lBcy3UrBWrPG9mzvq4PKMxA==", "dev": true, "license": "MIT", "dependencies": { @@ -4944,13 +4944,13 @@ "url": "https://opencollective.com/storybook" }, "peerDependencies": { - "storybook": "^8.6.0" + "storybook": "^8.6.2" } }, "node_modules/@storybook/blocks": { - "version": "8.6.0", - "resolved": "https://registry.npmjs.org/@storybook/blocks/-/blocks-8.6.0.tgz", - "integrity": "sha512-3PNxlB5Ooj8CIhttbDxeV6kW7ui+2GEdTngtqhnsUHVjzeTKpilsk2lviOeUzqlyq5FDK+rhpZ3L3DJ9pDvioA==", + "version": "8.6.2", + "resolved": "https://registry.npmjs.org/@storybook/blocks/-/blocks-8.6.2.tgz", + "integrity": "sha512-yYskHxUDJcBcRRSTZ95agqO3gZ4gLK9/1QZvANa6+Hb23Z5tGpNDHzLFGZePUJGRBqPPaNraay+SCI1LBY3/yw==", "dev": true, "license": "MIT", "dependencies": { @@ -4964,7 +4964,7 @@ "peerDependencies": { "react": "^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0", "react-dom": "^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0", - "storybook": "^8.6.0" + "storybook": "^8.6.2" }, "peerDependenciesMeta": { "react": { @@ -4976,13 +4976,13 @@ } }, "node_modules/@storybook/builder-vite": { - "version": "8.6.0", - "resolved": "https://registry.npmjs.org/@storybook/builder-vite/-/builder-vite-8.6.0.tgz", - "integrity": "sha512-Bdc5fXLJbPdQo2eJ3dDNhfhWuQOME2KWvrixnsfo57IOhDa5B81jVcDBQIIgB9K1NQDRGyaWfYCcKZqy16yPlQ==", + "version": "8.6.2", + "resolved": "https://registry.npmjs.org/@storybook/builder-vite/-/builder-vite-8.6.2.tgz", + "integrity": "sha512-FE52FnGJhRqxLA9FVtS0fiNI5XfIjuewPlSWYviMJ5JcR/OfHUI3s97IBi/tDgeVcktDCjzMOC63YdYTest68A==", "dev": true, "license": "MIT", "dependencies": { - "@storybook/csf-plugin": "8.6.0", + "@storybook/csf-plugin": "8.6.2", "browser-assert": "^1.2.1", "ts-dedent": "^2.0.0" }, @@ -4991,14 +4991,14 @@ "url": "https://opencollective.com/storybook" }, "peerDependencies": { - "storybook": "^8.6.0", + "storybook": "^8.6.2", "vite": "^4.0.0 || ^5.0.0 || ^6.0.0" } }, "node_modules/@storybook/components": { - "version": "8.6.0", - "resolved": "https://registry.npmjs.org/@storybook/components/-/components-8.6.0.tgz", - "integrity": "sha512-k5MQAuLPt5KOaa5J4QvX/WKucaiFTMJiEX5lsSaY6qON6Sx8PtnLQxVwWF7BIMW/jLpd94BUxrVjVrQKlwoLKQ==", + "version": "8.6.2", + "resolved": "https://registry.npmjs.org/@storybook/components/-/components-8.6.2.tgz", + "integrity": "sha512-tPEgj40YMkIE8KfElh5gf3s/B/KOcFKBpf6k7Nn3wZAu+dSifrGNyU33lecHjfkRHO/ZK1QYF7kIkCkPu/SKQA==", "dev": true, "license": "MIT", "funding": { @@ -5010,13 +5010,13 @@ } }, "node_modules/@storybook/core": { - "version": "8.6.0", - "resolved": "https://registry.npmjs.org/@storybook/core/-/core-8.6.0.tgz", - "integrity": "sha512-UzVo2sNz8PZuDp++/R9NBtjupSXhvxS8lptYcwtk51b6MvcM4AL/b4V3PGryOVJDru9sMwz+pzaj7Jg8RVFMJA==", + "version": "8.6.2", + "resolved": "https://registry.npmjs.org/@storybook/core/-/core-8.6.2.tgz", + "integrity": "sha512-i8a/nUuzzH5RLKjPn8DM7l8xxuTdLZ6xbI4hgpruas3JY8lQq72I7qmH6pmI7ByjGangDWK1iPh+tghdKkS6KQ==", "dev": true, "license": "MIT", "dependencies": { - "@storybook/theming": "8.6.0", + "@storybook/theming": "8.6.2", "better-opn": "^3.0.2", "browser-assert": "^1.2.1", "esbuild": "^0.18.0 || ^0.19.0 || ^0.20.0 || ^0.21.0 || ^0.22.0 || ^0.23.0 || ^0.24.0 || ^0.25.0", @@ -5042,9 +5042,9 @@ } }, "node_modules/@storybook/csf-plugin": { - "version": "8.6.0", - "resolved": "https://registry.npmjs.org/@storybook/csf-plugin/-/csf-plugin-8.6.0.tgz", - "integrity": "sha512-Cd7LL4XQ8ccUDzJGxVyuzgsYuRYS5LVL4/ZNmAxikz9LtVrVFI/4RgFa5MvlQZc0twreoLtztFskziny8OiJUQ==", + "version": "8.6.2", + "resolved": "https://registry.npmjs.org/@storybook/csf-plugin/-/csf-plugin-8.6.2.tgz", + "integrity": "sha512-YqvtCTzAn4EJ+Da+QcY6oeGxrybeHohRiPwYN6gjGQOgRj0acp5CJakH9Nz/0/U3BaXrf+5YtfTEM+SWhlRROw==", "dev": true, "license": "MIT", "dependencies": { @@ -5055,7 +5055,7 @@ "url": "https://opencollective.com/storybook" }, "peerDependencies": { - "storybook": "^8.6.0" + "storybook": "^8.6.2" } }, "node_modules/@storybook/global": { @@ -5080,9 +5080,9 @@ } }, "node_modules/@storybook/instrumenter": { - "version": "8.6.0", - "resolved": "https://registry.npmjs.org/@storybook/instrumenter/-/instrumenter-8.6.0.tgz", - "integrity": "sha512-eEY/Hfa3Vj5Nv4vHRHlSqjoyW6oAKNK3rKIXfL/eawQwb7rKhzijDLG5YBH44Hh7dEPIqUp0LEdgpyIY7GXezg==", + "version": "8.6.2", + "resolved": "https://registry.npmjs.org/@storybook/instrumenter/-/instrumenter-8.6.2.tgz", + "integrity": "sha512-26z5KiAhS/j0DzPwpT08/JZ1Uy2D9TQOiD6pZ8f6H1UJyPhAuctJqAfMCC0rTAKBIWeA5KKxBbjd+lhiMsusRA==", "dev": true, "license": "MIT", "dependencies": { @@ -5094,13 +5094,13 @@ "url": "https://opencollective.com/storybook" }, "peerDependencies": { - "storybook": "^8.6.0" + "storybook": "^8.6.2" } }, "node_modules/@storybook/manager-api": { - "version": "8.6.0", - "resolved": "https://registry.npmjs.org/@storybook/manager-api/-/manager-api-8.6.0.tgz", - "integrity": "sha512-ddBibYrO3yQCdtZBqQYqfABjR9eS+llvt2NFDajfyQw+zmuNIZfw4BDGKH1WHE4wm/kXmlFFhPHXaHgAPTRPfQ==", + "version": "8.6.2", + "resolved": "https://registry.npmjs.org/@storybook/manager-api/-/manager-api-8.6.2.tgz", + "integrity": "sha512-75yx3xSDRU1B4dsf2OSJev7VAvR+6SjWUExENmMGXa0PpoO0MBZqMKdIufKMPsRtw77ugKGfS04MWt4yc5lgRQ==", "dev": true, "license": "MIT", "funding": { @@ -5112,9 +5112,9 @@ } }, "node_modules/@storybook/preview-api": { - "version": "8.6.0", - "resolved": "https://registry.npmjs.org/@storybook/preview-api/-/preview-api-8.6.0.tgz", - "integrity": "sha512-c/sZj4Tb+DtdCndcjoFUneUwl2XUdQckqN4nf1SuIJ/BXRbAexlD04fvPJ4wzmwUNg8EQF7BhTWVNDa1RvJz2w==", + "version": "8.6.2", + "resolved": "https://registry.npmjs.org/@storybook/preview-api/-/preview-api-8.6.2.tgz", + "integrity": "sha512-hkKmQ9OWlCpS2mHYsuWTbXMfeLx90fiWdUblTBIUQnj8VLhSbNtmeBZdZRkz33uYHFkAqZ3F2nQ9I2iTv8AmwA==", "dev": true, "license": "MIT", "funding": { @@ -5126,18 +5126,18 @@ } }, "node_modules/@storybook/react": { - "version": "8.6.0", - "resolved": "https://registry.npmjs.org/@storybook/react/-/react-8.6.0.tgz", - "integrity": "sha512-go0KhCFcOhxkTdaMCxeuJxmc/5CaiaO76+SBzIoPIMWEh9tZQmKb+vojdKcFZswHjZV3zA1uJFUzyympspRffA==", + "version": "8.6.2", + "resolved": "https://registry.npmjs.org/@storybook/react/-/react-8.6.2.tgz", + "integrity": "sha512-f6mS9nydU2KGY3nIvu4WVUFmJNEjzmFLj86iznO9CK/pELH53e4RjuzXgIqfWIGxBpR0QyFMdwyWjaOB5ZKr7Q==", "dev": true, "license": "MIT", "dependencies": { - "@storybook/components": "8.6.0", + "@storybook/components": "8.6.2", "@storybook/global": "^5.0.0", - "@storybook/manager-api": "8.6.0", - "@storybook/preview-api": "8.6.0", - "@storybook/react-dom-shim": "8.6.0", - "@storybook/theming": "8.6.0" + "@storybook/manager-api": "8.6.2", + "@storybook/preview-api": "8.6.2", + "@storybook/react-dom-shim": "8.6.2", + "@storybook/theming": "8.6.2" }, "engines": { "node": ">=18.0.0" @@ -5147,10 +5147,10 @@ "url": "https://opencollective.com/storybook" }, "peerDependencies": { - "@storybook/test": "8.6.0", + "@storybook/test": "8.6.2", "react": "^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0-beta", "react-dom": "^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0-beta", - "storybook": "^8.6.0", + "storybook": "^8.6.2", "typescript": ">= 4.2.x" }, "peerDependenciesMeta": { @@ -5163,9 +5163,9 @@ } }, "node_modules/@storybook/react-dom-shim": { - "version": "8.6.0", - "resolved": "https://registry.npmjs.org/@storybook/react-dom-shim/-/react-dom-shim-8.6.0.tgz", - "integrity": "sha512-5Y+vMHhcx0xnaNsLQMbkmjc3zkDn/fGBNsiLH2e4POvW3ZQvOxjoyxAsEQaKwLtFgsdCFSd2tR89F6ItYrA2JQ==", + "version": "8.6.2", + "resolved": "https://registry.npmjs.org/@storybook/react-dom-shim/-/react-dom-shim-8.6.2.tgz", + "integrity": "sha512-8VTAaYtvtP3dx9AXk2lMTQ/o/hTBpL/a6C48JYWhfbU1UO6O0B4PUGADFJ8XWzobXRkTm7CR3RGLzA2oYgWxdA==", "dev": true, "license": "MIT", "funding": { @@ -5175,20 +5175,20 @@ "peerDependencies": { "react": "^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0-beta", "react-dom": "^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0-beta", - "storybook": "^8.6.0" + "storybook": "^8.6.2" } }, "node_modules/@storybook/react-vite": { - "version": "8.6.0", - "resolved": "https://registry.npmjs.org/@storybook/react-vite/-/react-vite-8.6.0.tgz", - "integrity": "sha512-uDQyf2u0Zki4qIavOu2jyGIlvmUOsgCpHXY+7KHr542ZIkXI3mGOi5/rwUxgNSHGD3JloYGdlt+4Md+9i5xEbA==", + "version": "8.6.2", + "resolved": "https://registry.npmjs.org/@storybook/react-vite/-/react-vite-8.6.2.tgz", + "integrity": "sha512-cj5B/mJuscMJPUx+6UgOFIivoY1RyZQDqluPo97qXY6eR5IRB9z/j1chv68BQUDAcjXCS02xTf9Kh5YcVreiIA==", "dev": true, "license": "MIT", "dependencies": { "@joshwooding/vite-plugin-react-docgen-typescript": "0.5.0", "@rollup/pluginutils": "^5.0.2", - "@storybook/builder-vite": "8.6.0", - "@storybook/react": "8.6.0", + "@storybook/builder-vite": "8.6.2", + "@storybook/react": "8.6.2", "find-up": "^5.0.0", "magic-string": "^0.30.0", "react-docgen": "^7.0.0", @@ -5203,10 +5203,10 @@ "url": "https://opencollective.com/storybook" }, "peerDependencies": { - "@storybook/test": "8.6.0", + "@storybook/test": "8.6.2", "react": "^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0-beta", "react-dom": "^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0-beta", - "storybook": "^8.6.0", + "storybook": "^8.6.2", "vite": "^4.0.0 || ^5.0.0 || ^6.0.0" }, "peerDependenciesMeta": { @@ -5216,14 +5216,14 @@ } }, "node_modules/@storybook/test": { - "version": "8.6.0", - "resolved": "https://registry.npmjs.org/@storybook/test/-/test-8.6.0.tgz", - "integrity": "sha512-qiiv4wh4FoxTb1PoiA/noo9HcLDqfTwL0svMoNpTy2Bxm6xajgg5zYmmIT4pKyQkMd9pfKKQKILok31VxAj8vw==", + "version": "8.6.2", + "resolved": "https://registry.npmjs.org/@storybook/test/-/test-8.6.2.tgz", + "integrity": "sha512-9GgLzIqYrHwpfffp43KJR9WIx3LkXIuej9BvSZk/KBWeBbOgqDbHG4CqC8P6uRl994RC91K85vdeRhAShkdtkA==", "dev": true, "license": "MIT", "dependencies": { "@storybook/global": "^5.0.0", - "@storybook/instrumenter": "8.6.0", + "@storybook/instrumenter": "8.6.2", "@testing-library/dom": "10.4.0", "@testing-library/jest-dom": "6.5.0", "@testing-library/user-event": "14.5.2", @@ -5235,7 +5235,7 @@ "url": "https://opencollective.com/storybook" }, "peerDependencies": { - "storybook": "^8.6.0" + "storybook": "^8.6.2" } }, "node_modules/@storybook/test/node_modules/@testing-library/jest-dom": { @@ -5295,9 +5295,9 @@ "license": "MIT" }, "node_modules/@storybook/theming": { - "version": "8.6.0", - "resolved": "https://registry.npmjs.org/@storybook/theming/-/theming-8.6.0.tgz", - "integrity": "sha512-te7dl0ZXnEyKS4LW+QHc3MP7nurWhWhmClY7G2WKNW9eHenb9zvXkcAQt6c4OWhrJi01CAYoXmZNJP0jEzxRRQ==", + "version": "8.6.2", + "resolved": "https://registry.npmjs.org/@storybook/theming/-/theming-8.6.2.tgz", + "integrity": "sha512-NF7tMZBbmh6rNf+uw5wVUpsVIwnbhLgauhQJONuQ8i+cI6cJEBaKjIC2uMWUBABqnj1LqGrHSEWVeeYwuAeUYg==", "dev": true, "license": "MIT", "funding": { @@ -5377,9 +5377,9 @@ } }, "node_modules/@tanstack/react-router": { - "version": "1.111.7", - "resolved": "https://registry.npmjs.org/@tanstack/react-router/-/react-router-1.111.7.tgz", - "integrity": "sha512-/hOWy7lPmVfRqbwIy2d9mvVLA6ZC4tbcgLDdMXCNRN93LMsGEHCTrgFADdSL2f/rvhPyHeYxsFazEo9+ktgUiw==", + "version": "1.111.11", + "resolved": "https://registry.npmjs.org/@tanstack/react-router/-/react-router-1.111.11.tgz", + "integrity": "sha512-8CZ1Yj38mdYBvBV9FCBEGGAWt2Usx7UDWnhFvUe8DyCX4e97+5pj5OJ/RrJMLXPc43Jf0H9Vu+VBeSJHK7oPog==", "license": "MIT", "dependencies": { "@tanstack/history": "1.99.13", @@ -5437,9 +5437,9 @@ } }, "node_modules/@tanstack/router-devtools": { - "version": "1.111.7", - "resolved": "https://registry.npmjs.org/@tanstack/router-devtools/-/router-devtools-1.111.7.tgz", - "integrity": "sha512-xZpiIWy/HBhpYUqUxT1dNUn5smQhWhkgjNlJOATzrm81G5T3l2jEr79XPXqwRndWzu2WKqv1kPkScC0ekRgE7Q==", + "version": "1.111.11", + "resolved": "https://registry.npmjs.org/@tanstack/router-devtools/-/router-devtools-1.111.11.tgz", + "integrity": "sha512-gZ7ZHvSUoabI8I2UAYPMWqYnZ98dqQ+qzZUWw0Ccv0fQvueIYnau097z6wx8RMpaOrwpyZ2ytwH2LgU7gJVwXg==", "dev": true, "license": "MIT", "dependencies": { @@ -5454,7 +5454,7 @@ "url": "https://github.com/sponsors/tannerlinsley" }, "peerDependencies": { - "@tanstack/react-router": "^1.111.7", + "@tanstack/react-router": "^1.111.11", "csstype": "^3.0.10", "react": ">=18.0.0 || >=19.0.0", "react-dom": ">=18.0.0 || >=19.0.0" @@ -5466,9 +5466,9 @@ } }, "node_modules/@tanstack/router-generator": { - "version": "1.111.7", - "resolved": "https://registry.npmjs.org/@tanstack/router-generator/-/router-generator-1.111.7.tgz", - "integrity": "sha512-+jHX35iF45NHQvHzXuLgyCILUUTyMl3EeClKNkfdaKLvV1adwGDQr24cSKDQLmNKEDXGTijBI5nX8ntkKo5oyA==", + "version": "1.111.12", + "resolved": "https://registry.npmjs.org/@tanstack/router-generator/-/router-generator-1.111.12.tgz", + "integrity": "sha512-2mxzxT0k1I8So9Shq05kbjkvEZ4KtUGqcwoE2eAdrQkkzQLm26lSazSgVis8EYV7leHX9fSaN5kQte0FrXjX5g==", "dev": true, "license": "MIT", "dependencies": { @@ -5485,7 +5485,7 @@ "url": "https://github.com/sponsors/tannerlinsley" }, "peerDependencies": { - "@tanstack/react-router": "^1.111.7" + "@tanstack/react-router": "^1.111.11" }, "peerDependenciesMeta": { "@tanstack/react-router": { @@ -5494,9 +5494,9 @@ } }, "node_modules/@tanstack/router-plugin": { - "version": "1.111.7", - "resolved": "https://registry.npmjs.org/@tanstack/router-plugin/-/router-plugin-1.111.7.tgz", - "integrity": "sha512-aiT/j2OadGbqEWTZUY53o2UeVQIR11+S1h1Gq6GYxQmD/OjdyK/WiMighBK5zeryeWYG4XeC8eFlXMoyuG0v+g==", + "version": "1.111.12", + "resolved": "https://registry.npmjs.org/@tanstack/router-plugin/-/router-plugin-1.111.12.tgz", + "integrity": "sha512-lljCSvzwhFT8FAgUYHFsZ6spAuGS1V734sZIapB/qZXs4ii6BMtKS4O3Cp+KbQD9javIelVpvSr4fNY0WjaFoQ==", "dev": true, "license": "MIT", "dependencies": { @@ -5507,7 +5507,7 @@ "@babel/traverse": "^7.26.8", "@babel/types": "^7.26.8", "@tanstack/router-core": "^1.111.7", - "@tanstack/router-generator": "^1.111.7", + "@tanstack/router-generator": "^1.111.12", "@tanstack/router-utils": "^1.102.2", "@tanstack/virtual-file-routes": "^1.99.0", "@types/babel__core": "^7.20.5", @@ -5527,7 +5527,7 @@ }, "peerDependencies": { "@rsbuild/core": ">=1.0.2", - "@tanstack/react-router": "^1.111.7", + "@tanstack/react-router": "^1.111.11", "vite": ">=5.0.0 || >=6.0.0", "vite-plugin-solid": "^2.11.2", "webpack": ">=5.92.0" @@ -5585,13 +5585,13 @@ } }, "node_modules/@tanstack/router-vite-plugin": { - "version": "1.111.7", - "resolved": "https://registry.npmjs.org/@tanstack/router-vite-plugin/-/router-vite-plugin-1.111.7.tgz", - "integrity": "sha512-32RG+4KLKMUczysyEF5QZHaoT41/XzZN/QCLzg0VvXKn06fFIuI8+yejskbROgOK3+feOqHejUda5BJh9LHVgA==", + "version": "1.111.12", + "resolved": "https://registry.npmjs.org/@tanstack/router-vite-plugin/-/router-vite-plugin-1.111.12.tgz", + "integrity": "sha512-1NunQqZeZ0LyqrfXJzOzoAJ4ICSA9XFMeFgf/IvZvdgkrOfcyR8tx8MoavcMIpwG1JheCqqJQIOgqe6pULPbog==", "dev": true, "license": "MIT", "dependencies": { - "@tanstack/router-plugin": "^1.111.7" + "@tanstack/router-plugin": "^1.111.12" }, "engines": { "node": ">=12" @@ -11895,9 +11895,9 @@ } }, "node_modules/recast": { - "version": "0.23.9", - "resolved": "https://registry.npmjs.org/recast/-/recast-0.23.9.tgz", - "integrity": "sha512-Hx/BGIbwj+Des3+xy5uAtAbdCyqK9y9wbBcDFDYanLS9JnMqf7OeF87HQwUimE87OEc72mr6tkKUKMBBL+hF9Q==", + "version": "0.23.10", + "resolved": "https://registry.npmjs.org/recast/-/recast-0.23.10.tgz", + "integrity": "sha512-mbCmRMJUKCJ1h41V0cu2C26ULBURwuoZ34C9rChjcDaeJ/4Kv5al3O2HPwTs2m0wQ1vGhMY+tguhzU1aE8md1A==", "dev": true, "license": "MIT", "dependencies": { @@ -12609,13 +12609,13 @@ "license": "MIT" }, "node_modules/storybook": { - "version": "8.6.0", - "resolved": "https://registry.npmjs.org/storybook/-/storybook-8.6.0.tgz", - "integrity": "sha512-NEHCK2nXogw7WxAkJfMwPnc5Cmh/KqVNrdaFeXBAKhC2Zr1FTZIiCR5nSUT85run44Wkpmo7qvUoKvII9GOWbA==", + "version": "8.6.2", + "resolved": "https://registry.npmjs.org/storybook/-/storybook-8.6.2.tgz", + "integrity": "sha512-IkQGRNImyN14+tx/9KLg9k5xKBgrkWaPFhfwTCxUZUzLNClbVrxkkXyjFaks9kPVQIEUVPGQCiGFqypUiwoM6g==", "dev": true, "license": "MIT", "dependencies": { - "@storybook/core": "8.6.0" + "@storybook/core": "8.6.2" }, "bin": { "getstorybook": "bin/index.cjs", @@ -12879,9 +12879,9 @@ } }, "node_modules/swagger-ui-dist": { - "version": "5.19.0", - "resolved": "https://registry.npmjs.org/swagger-ui-dist/-/swagger-ui-dist-5.19.0.tgz", - "integrity": "sha512-bSVZeYaqanMFeW5ZY3+EejFbsjkjazYxm1I7Lz3xayYz5XU3m2aUzvuPC0jI95WCQdduszHYV3ER4buQoy8DXA==", + "version": "5.20.0", + "resolved": "https://registry.npmjs.org/swagger-ui-dist/-/swagger-ui-dist-5.20.0.tgz", + "integrity": "sha512-V5pozVTZxivdoQq/SQWxj3A4cOu5opk9MEbcZANX3Pj8X8xCrD1QCtBT7744Pz9msOvt0nnmy9JvM/9PGonCdg==", "license": "Apache-2.0", "dependencies": { "@scarf/scarf": "=1.4.0" diff --git a/frontend/package.json b/frontend/package.json index be55bb442..fe1c5811e 100644 --- a/frontend/package.json +++ b/frontend/package.json @@ -23,7 +23,7 @@ "@radix-ui/react-collapsible": "^1.1.3", "@radix-ui/react-dialog": "^1.1.6", "@tanstack/react-query": "^5.66.9", - "@tanstack/react-router": "^1.111.7", + "@tanstack/react-router": "^1.111.11", "@vector-im/compound-design-tokens": "4.0.0", "@vector-im/compound-web": "^7.6.4", "@zxcvbn-ts/core": "^3.0.4", @@ -34,7 +34,7 @@ "react": "^19.0.0", "react-dom": "^19.0.0", "react-i18next": "^15.4.1", - "swagger-ui-dist": "^5.19.0", + "swagger-ui-dist": "^5.20.0", "valibot": "^1.0.0-rc.2", "vaul": "^1.1.2" }, @@ -47,14 +47,14 @@ "@graphql-codegen/cli": "^5.0.5", "@graphql-codegen/client-preset": "^4.6.4", "@graphql-codegen/typescript-msw": "^3.0.0", - "@storybook/addon-essentials": "^8.6.0", - "@storybook/addon-interactions": "^8.6.0", - "@storybook/react": "^8.6.0", - "@storybook/react-vite": "^8.6.0", + "@storybook/addon-essentials": "^8.6.2", + "@storybook/addon-interactions": "^8.6.2", + "@storybook/react": "^8.6.2", + "@storybook/react-vite": "^8.6.2", "@storybook/test": "^8.5.5", "@tanstack/react-query-devtools": "^5.66.9", - "@tanstack/router-devtools": "^1.111.7", - "@tanstack/router-vite-plugin": "^1.111.7", + "@tanstack/router-devtools": "^1.111.11", + "@tanstack/router-vite-plugin": "^1.111.12", "@testing-library/jest-dom": "^6.6.3", "@testing-library/react": "^16.2.0", "@testing-library/user-event": "^14.6.1", diff --git a/policies/register/register.rego b/policies/register/register.rego index 6189c3926..6a36f9611 100644 --- a/policies/register/register.rego +++ b/policies/register/register.rego @@ -14,6 +14,14 @@ allow if { count(violation) == 0 } +username_allowed if { + not data.registration.allowed_usernames +} + +username_allowed if { + common.matches_string_constraints(input.username, data.registration.allowed_usernames) +} + # METADATA # entrypoint: true violation contains {"field": "username", "code": "username-too-short", "msg": "username too short"} if { @@ -39,6 +47,20 @@ violation contains { not regex.match(`^[a-z0-9.=_/-]+$`, input.username) } +violation contains { + "field": "username", "code": "username-banned", + "msg": "username is banned", +} if { + common.matches_string_constraints(input.username, data.registration.banned_usernames) +} + +violation contains { + "field": "username", "code": "username-not-allowed", + "msg": "username is not allowed", +} if { + not username_allowed +} + violation contains {"msg": "unspecified registration method"} if { not input.registration_method } diff --git a/policies/register/register_test.rego b/policies/register/register_test.rego index 51105ea39..040cdcc5d 100644 --- a/policies/register/register_test.rego +++ b/policies/register/register_test.rego @@ -75,6 +75,20 @@ test_numeric_username if { not register.allow with input as {"username": "1234", "registration_method": "upstream-oauth2"} } +test_allowed_username if { + register.allow with input as {"username": "hello", "registration_method": "upstream-oauth2"} + with data.registration.allowed_usernames.literals as ["hello"] + not register.allow with input as {"username": "hello", "registration_method": "upstream-oauth2"} + with data.registration.allowed_usernames.literals as ["world"] +} + +test_banned_username if { + not register.allow with input as {"username": "hello", "registration_method": "upstream-oauth2"} + with data.registration.banned_usernames.literals as ["hello"] + register.allow with input as {"username": "hello", "registration_method": "upstream-oauth2"} + with data.registration.banned_usernames.literals as ["world"] +} + test_ip_ban if { not register.allow with input as { "username": "hello", diff --git a/templates/components/field.html b/templates/components/field.html index d26fc3b66..455206854 100644 --- a/templates/components/field.html +++ b/templates/components/field.html @@ -69,6 +69,10 @@ Please see LICENSE in the repository root for full details. {{ _("mas.errors.username_invalid_chars") }} {% elif error.code == "username-all-numeric" %} {{ _("mas.errors.username_all_numeric") }} + {% elif error.code == "username-banned" %} + {{ _("mas.errors.username_banned") }} + {% elif error.code == "username-not-allowed" %} + {{ _("mas.errors.username_not_allowed") }} {% elif error.code == "email-domain-not-allowed" %} {{ _("mas.errors.email_domain_not_allowed") }} {% elif error.code == "email-domain-banned" %} diff --git a/translations/en.json b/translations/en.json index 70794197d..39e2d46b7 100644 --- a/translations/en.json +++ b/translations/en.json @@ -299,23 +299,23 @@ }, "denied_policy": "Denied by policy: %(policy)s", "@denied_policy": { - "context": "components/errors.html:17:7-58, components/field.html:81:19-70" + "context": "components/errors.html:17:7-58, components/field.html:85:19-70" }, "email_banned": "Email is banned by the server policy", "@email_banned": { - "context": "components/field.html:79:19-47" + "context": "components/field.html:83:19-47" }, "email_domain_banned": "Email domain is banned by the server policy", "@email_domain_banned": { - "context": "components/field.html:75:19-54" + "context": "components/field.html:79:19-54" }, "email_domain_not_allowed": "Email domain is not allowed by the server policy", "@email_domain_not_allowed": { - "context": "components/field.html:73:19-59" + "context": "components/field.html:77:19-59" }, "email_not_allowed": "Email is not allowed by the server policy", "@email_not_allowed": { - "context": "components/field.html:77:19-52" + "context": "components/field.html:81:19-52" }, "field_required": "This field is required", "@field_required": { @@ -327,7 +327,7 @@ }, "password_mismatch": "Password fields don't match", "@password_mismatch": { - "context": "components/errors.html:13:7-40, components/field.html:84:17-50" + "context": "components/errors.html:13:7-40, components/field.html:88:17-50" }, "rate_limit_exceeded": "You've made too many requests in a short period. Please wait a few minutes and try again.", "@rate_limit_exceeded": { @@ -337,10 +337,20 @@ "@username_all_numeric": { "context": "components/field.html:71:19-55" }, + "username_banned": "Username is banned by the server policy", + "@username_banned": { + "context": "components/field.html:73:19-50", + "description": "Error message shown on registration, when the username matches a pattern that is banned by the server policy." + }, "username_invalid_chars": "Username contains invalid characters. Use lowercase letters, numbers, dashes and underscores only.", "@username_invalid_chars": { "context": "components/field.html:69:19-57" }, + "username_not_allowed": "Username is not allowed by the server policy", + "@username_not_allowed": { + "context": "components/field.html:75:19-55", + "description": "Error message shown on registration, when the username *does not match* any of the patterns that are allowed by the server policy." + }, "username_taken": "This username is already taken", "@username_taken": { "context": "components/field.html:62:17-47" @@ -424,7 +434,7 @@ }, "or_separator": "Or", "@or_separator": { - "context": "components/field.html:103:10-31", + "context": "components/field.html:107:10-31", "description": "Separator between the login methods" }, "policy_violation": {