diff --git a/.github/workflows/reviewers.yml b/.github/workflows/reviewers.yml index f22e44d7cbff..03d8caa2661b 100644 --- a/.github/workflows/reviewers.yml +++ b/.github/workflows/reviewers.yml @@ -63,28 +63,6 @@ jobs: permission-members: read permission-pull-requests: write - - name: Log current API rate limits (app-token) - if: ${{ steps.app-token.outputs.token }} - env: - GH_TOKEN: ${{ steps.app-token.outputs.token }} - run: gh api /rate_limit | jq - - - name: Requesting code owner reviews - if: steps.app-token.outputs.token - env: - GH_TOKEN: ${{ steps.app-token.outputs.token }} - REPOSITORY: ${{ github.repository }} - NUMBER: ${{ github.event.number }} - # Don't do anything on draft PRs - DRY_MODE: ${{ github.event.pull_request.draft && '1' || '' }} - run: result/bin/request-code-owner-reviews.sh "$REPOSITORY" "$NUMBER" ci/OWNERS - - - name: Log current API rate limits (app-token) - if: ${{ steps.app-token.outputs.token }} - env: - GH_TOKEN: ${{ steps.app-token.outputs.token }} - run: gh api /rate_limit | jq - - name: Log current API rate limits (github.token) env: GH_TOKEN: ${{ github.token }} @@ -149,7 +127,7 @@ jobs: GH_TOKEN: ${{ github.token }} run: gh api /rate_limit | jq - - name: Requesting maintainer reviews + - name: Requesting reviews if: ${{ steps.app-token.outputs.token }} env: GH_TOKEN: ${{ github.token }} @@ -164,6 +142,7 @@ jobs: # There appears to be no API to request reviews based on GitHub IDs jq -r 'keys[]' comparison/maintainers.json \ | while read -r id; do gh api /user/"$id" --jq .login; done \ + | cat comparison/owners.txt - \ | GH_TOKEN="$APP_GH_TOKEN" result/bin/request-reviewers.sh "$REPOSITORY" "$NUMBER" "$AUTHOR" - name: Log current API rate limits (app-token) diff --git a/ci/README.md b/ci/README.md index df0b9a12384a..500abbfb637f 100644 --- a/ci/README.md +++ b/ci/README.md @@ -43,8 +43,10 @@ These issues effectively list PRs the merge bot has interacted with. To ensure security and a focused utility, the bot adheres to specific limitations: - The PR targets `master`, `staging`, or `staging-next`. -- The PR only touches files located under `pkgs/by-name/*`. -- The PR is authored by [@r-ryantm](https://nix-community.github.io/nixpkgs-update/r-ryantm/) or a [committer][@NixOS/nixpkgs-committers]. +- The PR only touches packages located under `pkgs/by-name/*`. +- The PR is either: + - authored by a [committer][@NixOS/nixpkgs-committers], or + - created by [@r-ryantm](https://nix-community.github.io/nixpkgs-update/r-ryantm/). - The user attempting to merge is a member of [@NixOS/nixpkgs-maintainers]. - The user attempting to merge is a maintainer of all packages touched by the PR. diff --git a/ci/eval/compare/default.nix b/ci/eval/compare/default.nix index eabc28af4d36..9791d26e9550 100644 --- a/ci/eval/compare/default.nix +++ b/ci/eval/compare/default.nix @@ -7,6 +7,7 @@ python3, stdenvNoCC, makeWrapper, + codeowners, }: let python = python3.withPackages (ps: [ @@ -48,6 +49,7 @@ in { combinedDir, touchedFilesJson, + ownersFile ? ../../OWNERS, }: let # Usually we expect a derivation, but when evaluating in multiple separate steps, we pass @@ -174,6 +176,7 @@ runCommand "compare" nativeBuildInputs = map lib.getBin [ jq cmp-stats + codeowners ]; maintainers = builtins.toJSON maintainers; packages = builtins.toJSON packages; @@ -222,6 +225,43 @@ runCommand "compare" } >> $out/step-summary.md fi + jq -r '.[]' "${touchedFilesJson}" > ./touched-files + readarray -t touchedFiles < ./touched-files + echo "This PR touches ''${#touchedFiles[@]} files" + + # TODO: Move ci/OWNERS to Nix and produce owners.json instead of owners.txt. + touch "$out/owners.txt" + for file in "''${touchedFiles[@]}"; do + result=$(codeowners --file "${ownersFile}" "$file") + + # Remove the file prefix and trim the surrounding spaces + read -r owners <<< "''${result#"$file"}" + if [[ "$owners" == "(unowned)" ]]; then + echo "File $file is unowned" + continue + fi + echo "File $file is owned by $owners" + + # Split up multiple owners, separated by arbitrary amounts of spaces + IFS=" " read -r -a entries <<< "$owners" + + for entry in "''${entries[@]}"; do + # GitHub technically also supports Emails as code owners, + # but we can't easily support that, so let's not + if [[ ! "$entry" =~ @(.*) ]]; then + echo -e "\e[33mCodeowner \"$entry\" for file $file is not valid: Must start with \"@\"\e[0m" + # Don't fail, because the PR for which this script runs can't fix it, + # it has to be fixed in the base branch + continue + fi + # The first regex match is everything after the @ + entry=''${BASH_REMATCH[1]} + + echo "$entry" >> "$out/owners.txt" + done + + done + cp "$maintainersPath" "$out/maintainers.json" cp "$packagesPath" "$out/packages.json" '' diff --git a/ci/github-script/merge.js b/ci/github-script/merge.js index 10e957db0362..5128124ac2eb 100644 --- a/ci/github-script/merge.js +++ b/ci/github-script/merge.js @@ -1,33 +1,15 @@ -// Caching the list of committers saves API requests when running the bot on the schedule and -// processing many PRs at once. -let committers - -async function runChecklist({ github, context, pull_request, maintainers }) { - const pull_number = pull_request.number - - if (!committers) { - if (context.eventName === 'pull_request') { - // We have no chance of getting a token in the pull_request context with the right - // permissions to access the members endpoint below. Thus, we're pretending to have - // no committers. This is OK; because this is only for the Test workflow, not for - // real use. - committers = new Set() - } else { - committers = github - .paginate(github.rest.teams.listMembersInOrg, { - org: context.repo.owner, - team_slug: 'nixpkgs-committers', - per_page: 100, - }) - .then((members) => new Set(members.map(({ id }) => id))) - } - } - - const files = await github.paginate(github.rest.pulls.listFiles, { - ...context.repo, - pull_number, - per_page: 100, - }) +function runChecklist({ + committers, + files, + pull_request, + log, + maintainers, + user, + userIsMaintainer, +}) { + const allByName = files.every(({ filename }) => + filename.startsWith('pkgs/by-name/'), + ) const packages = files .filter(({ filename }) => filename.startsWith('pkgs/by-name/')) @@ -45,19 +27,39 @@ async function runChecklist({ github, context, pull_request, maintainers }) { 'staging', 'staging-next', ].includes(pull_request.base.ref), - 'PR touches only files in `pkgs/by-name/`.': files.every(({ filename }) => - filename.startsWith('pkgs/by-name/'), - ), - 'PR authored by r-ryantm or committer.': - pull_request.user.login === 'r-ryantm' || - (await committers).has(pull_request.user.id), - 'PR has maintainers eligible for merge.': eligible.size > 0, + 'PR touches only packages in `pkgs/by-name/`.': allByName, + 'PR is at least one of:': { + 'Authored by a committer.': committers.has(pull_request.user.id), + 'Created by r-ryantm.': pull_request.user.login === 'r-ryantm', + }, } + if (user) { + checklist[ + `${user.login} is a member of [@NixOS/nixpkgs-maintainers](https://github.com/orgs/NixOS/teams/nixpkgs-maintainers).` + ] = userIsMaintainer + if (allByName) { + // We can only determine the below, if all packages are in by-name, since + // we can't reliably relate changed files to packages outside by-name. + checklist[`${user.login} is a maintainer of all touched packages.`] = + eligible.has(user.id) + } + } else { + // This is only used when no user is passed, i.e. for labeling. + checklist['PR has maintainers eligible to merge.'] = eligible.size > 0 + } + + const result = Object.values(checklist).every((v) => + typeof v === 'boolean' ? v : Object.values(v).some(Boolean), + ) + + log('checklist', JSON.stringify(checklist)) + log('eligible', JSON.stringify(Array.from(eligible))) + log('result', result) + return { checklist, - eligible, - result: Object.values(checklist).every(Boolean), + result, } } @@ -86,6 +88,10 @@ async function handleMergeComment({ github, body, node_id, reaction }) { ) } +// Caching the list of team members saves API requests when running the bot on the schedule and +// processing many PRs at once. +const members = {} + async function handleMerge({ github, context, @@ -98,15 +104,34 @@ async function handleMerge({ }) { const pull_number = pull_request.number - const { checklist, eligible, result } = await runChecklist({ - github, - context, - pull_request, - maintainers, + function getTeamMembers(team_slug) { + if (context.eventName === 'pull_request') { + // We have no chance of getting a token in the pull_request context with the right + // permissions to access the members endpoint below. Thus, we're pretending to have + // no members. This is OK; because this is only for the Test workflow, not for + // real use. + return new Set() + } + + if (!members[team_slug]) { + members[team_slug] = github + .paginate(github.rest.teams.listMembersInOrg, { + org: context.repo.owner, + team_slug, + per_page: 100, + }) + .then((members) => new Set(members.map(({ id }) => id))) + } + + return members[team_slug] + } + const committers = await getTeamMembers('nixpkgs-committers') + + const files = await github.paginate(github.rest.pulls.listFiles, { + ...context.repo, + pull_number, + per_page: 100, }) - log('checklist', JSON.stringify(checklist)) - log('eligible', JSON.stringify(Array.from(eligible))) - log('result', result) // Only look through comments *after* the latest (force) push. const latestChange = events.findLast(({ event }) => @@ -158,6 +183,7 @@ async function handleMerge({ log('Auto Merge failed', e.response.errors[0].message) } + // TODO: Observe whether the below is true and whether manual enqueue is actually needed. // Auto-merge doesn't work if the target branch has already run all CI, in which // case the PR must be enqueued explicitly. // We now have merge queues enabled on all development branches, thus don't need a @@ -217,23 +243,36 @@ async function handleMerge({ } } - const canUseMergeBot = await isMaintainer(comment.user.login) - const isEligible = eligible.has(comment.user.id) - const canMerge = result && canUseMergeBot && isEligible + const { result, checklist } = runChecklist({ + committers, + files, + pull_request, + log, + maintainers, + user: comment.user, + userIsMaintainer: await isMaintainer(comment.user.login), + }) const body = [ ``, + `@${comment.user.login} wants to merge this PR.`, '', - 'Requirements to merge this PR:', - ...Object.entries(checklist).map( - ([msg, res]) => `- :${res ? 'white_check_mark' : 'x'}: ${msg}`, + 'Requirements to merge this PR with `@NixOS/nixpkgs-merge-bot merge`:', + ...Object.entries(checklist).flatMap(([msg, res]) => + typeof res === 'boolean' + ? `- :${res ? 'white_check_mark' : 'x'}: ${msg}` + : [ + `- :${Object.values(res).some(Boolean) ? 'white_check_mark' : 'x'}: ${msg}`, + ...Object.entries(res).map( + ([msg, res]) => + ` - ${res ? ':white_check_mark:' : ':white_large_square:'} ${msg}`, + ), + ], ), - `- :${canUseMergeBot ? 'white_check_mark' : 'x'}: ${comment.user.login} can use the merge bot.`, - `- :${isEligible ? 'white_check_mark' : 'x'}: ${comment.user.login} is eligible to merge changes to the touched packages.`, '', ] - if (canMerge) { + if (result) { await react('ROCKET') try { body.push(`:heavy_check_mark: ${await merge()} (#306934)`) @@ -257,9 +296,17 @@ async function handleMerge({ }) } - if (canMerge) break + if (result) break } + const { result } = runChecklist({ + committers, + files, + pull_request, + log, + maintainers, + }) + // Returns a boolean, which indicates whether the PR is merge-bot eligible in principle. // This is used to set the respective label in bot.js. return result diff --git a/ci/request-reviews/default.nix b/ci/request-reviews/default.nix index 075ff52fd564..55a1889fe89f 100644 --- a/ci/request-reviews/default.nix +++ b/ci/request-reviews/default.nix @@ -3,20 +3,15 @@ stdenvNoCC, makeWrapper, coreutils, - codeowners, jq, - curl, github-cli, - gitMinimal, }: stdenvNoCC.mkDerivation { name = "request-reviews"; src = lib.fileset.toSource { root = ./.; fileset = lib.fileset.unions [ - ./get-code-owners.sh ./request-reviewers.sh - ./request-code-owner-reviews.sh ]; }; nativeBuildInputs = [ makeWrapper ]; @@ -29,11 +24,8 @@ stdenvNoCC.mkDerivation { --set PATH ${ lib.makeBinPath [ coreutils - codeowners jq - curl github-cli - gitMinimal ] } done diff --git a/ci/request-reviews/get-code-owners.sh b/ci/request-reviews/get-code-owners.sh deleted file mode 100755 index 13a377429b92..000000000000 --- a/ci/request-reviews/get-code-owners.sh +++ /dev/null @@ -1,97 +0,0 @@ -#!/usr/bin/env bash - -# Get the code owners of the files changed by a PR, returning one username per line - -set -euo pipefail - -log() { - echo "$@" >&2 -} - -if (( "$#" < 4 )); then - log "Usage: $0 GIT_REPO OWNERS_FILE BASE_REF HEAD_REF" - exit 1 -fi - -gitRepo=$1 -ownersFile=$2 -baseRef=$3 -headRef=$4 - -tmp=$(mktemp -d) -trap 'rm -rf "$tmp"' exit - -git -C "$gitRepo" diff --name-only --merge-base "$baseRef" "$headRef" > "$tmp/touched-files" -readarray -t touchedFiles < "$tmp/touched-files" -log "This PR touches ${#touchedFiles[@]} files" - -# Get the owners file from the base, because we don't want to allow PRs to -# remove code owners to avoid pinging them -git -C "$gitRepo" show "$baseRef":"$ownersFile" > "$tmp"/codeowners - -# Associative array with the user as the key for easy de-duplication -# Make sure to always lowercase keys to avoid duplicates with different casings -declare -A users=() - -for file in "${touchedFiles[@]}"; do - result=$(codeowners --file "$tmp"/codeowners "$file") - - # Remove the file prefix and trim the surrounding spaces - read -r owners <<< "${result#"$file"}" - if [[ "$owners" == "(unowned)" ]]; then - log "File $file is unowned" - continue - fi - log "File $file is owned by $owners" - - # Split up multiple owners, separated by arbitrary amounts of spaces - IFS=" " read -r -a entries <<< "$owners" - - for entry in "${entries[@]}"; do - # GitHub technically also supports Emails as code owners, - # but we can't easily support that, so let's not - if [[ ! "$entry" =~ @(.*) ]]; then - warn -e "\e[33mCodeowner \"$entry\" for file $file is not valid: Must start with \"@\"\e[0m" >&2 - # Don't fail, because the PR for which this script runs can't fix it, - # it has to be fixed in the base branch - continue - fi - # The first regex match is everything after the @ - entry=${BASH_REMATCH[1]} - - if [[ "$entry" =~ (.*)/(.*) ]]; then - # Teams look like $org/$team - org=${BASH_REMATCH[1]} - team=${BASH_REMATCH[2]} - - # Instead of requesting a review from the team itself, - # we request reviews from the individual users. - # This is because once somebody from a team reviewed the PR, - # the API doesn't expose that the team was already requested for a review, - # so we wouldn't be able to avoid rerequesting reviews - # without saving some some extra state somewhere - - # We could also consider implementing a more advanced heuristic - # in the future that e.g. only pings one team member, - # but escalates to somebody else if that member doesn't respond in time. - gh api \ - --cache=1h \ - -H "Accept: application/vnd.github+json" \ - -H "X-GitHub-Api-Version: 2022-11-28" \ - "/orgs/$org/teams/$team/members" \ - --jq '.[].login' > "$tmp/team-members" - readarray -t members < "$tmp/team-members" - log "Team $entry has these members: ${members[*]}" - - for user in "${members[@]}"; do - users[${user,,}]= - done - else - # Everything else is a user - users[${entry,,}]= - fi - done - -done - -printf "%s\n" "${!users[@]}" diff --git a/ci/request-reviews/request-code-owner-reviews.sh b/ci/request-reviews/request-code-owner-reviews.sh deleted file mode 100755 index 663285ae03fe..000000000000 --- a/ci/request-reviews/request-code-owner-reviews.sh +++ /dev/null @@ -1,60 +0,0 @@ -#!/usr/bin/env bash - -# Requests reviews for a PR - -set -euo pipefail -tmp=$(mktemp -d) -trap 'rm -rf "$tmp"' exit -SCRIPT_DIR=$(dirname "$0") - -log() { - echo "$@" >&2 -} - -if (( $# < 3 )); then - log "Usage: $0 GITHUB_REPO PR_NUMBER OWNERS_FILE" - exit 1 -fi -baseRepo=$1 -prNumber=$2 -ownersFile=$3 - -log "Fetching PR info" -prInfo=$(gh api \ - -H "Accept: application/vnd.github+json" \ - -H "X-GitHub-Api-Version: 2022-11-28" \ - "/repos/$baseRepo/pulls/$prNumber") - -baseBranch=$(jq -r .base.ref <<< "$prInfo") -log "Base branch: $baseBranch" -prRepo=$(jq -r .head.repo.full_name <<< "$prInfo") -log "PR repo: $prRepo" -prBranch=$(jq -r .head.ref <<< "$prInfo") -log "PR branch: $prBranch" -prAuthor=$(jq -r .user.login <<< "$prInfo") -log "PR author: $prAuthor" - -extraArgs=() -if pwdRepo=$(git rev-parse --show-toplevel 2>/dev/null); then - # Speedup for local runs - extraArgs+=(--reference-if-able "$pwdRepo") -fi - -log "Fetching Nixpkgs commit history" -# We only need the commit history, not the contents, so we can do a tree-less clone using tree:0 -# https://github.blog/open-source/git/get-up-to-speed-with-partial-clone-and-shallow-clone/#user-content-quick-summary -git clone --bare --filter=tree:0 --no-tags --origin upstream "${extraArgs[@]}" https://github.com/"$baseRepo".git "$tmp"/nixpkgs.git - -log "Fetching the PR commit history" -# Fetch the PR -git -C "$tmp/nixpkgs.git" remote add fork https://github.com/"$prRepo".git -# This remote config is the same as --filter=tree:0 when cloning -git -C "$tmp/nixpkgs.git" config remote.fork.partialclonefilter tree:0 -git -C "$tmp/nixpkgs.git" config remote.fork.promisor true - -git -C "$tmp/nixpkgs.git" fetch --no-tags fork "$prBranch" -headRef=$(git -C "$tmp/nixpkgs.git" rev-parse refs/remotes/fork/"$prBranch") - -log "Requesting reviews from code owners" -"$SCRIPT_DIR"/get-code-owners.sh "$tmp/nixpkgs.git" "$ownersFile" "$baseBranch" "$headRef" | \ - "$SCRIPT_DIR"/request-reviewers.sh "$baseRepo" "$prNumber" "$prAuthor" diff --git a/ci/request-reviews/request-reviewers.sh b/ci/request-reviews/request-reviewers.sh index 1c105e385d28..a7cde16eb97b 100755 --- a/ci/request-reviews/request-reviewers.sh +++ b/ci/request-reviews/request-reviewers.sh @@ -33,9 +33,41 @@ prAuthor=$3 tmp=$(mktemp -d) trap 'rm -rf "$tmp"' exit +# Associative array with the user as the key for easy de-duplication +# Make sure to always lowercase keys to avoid duplicates with different casings declare -A users=() while read -r handle && [[ -n "$handle" ]]; do - users[${handle,,}]= + if [[ "$handle" =~ (.*)/(.*) ]]; then + # Teams look like $org/$team + org=${BASH_REMATCH[1]} + team=${BASH_REMATCH[2]} + + # Instead of requesting a review from the team itself, + # we request reviews from the individual users. + # This is because once somebody from a team reviewed the PR, + # the API doesn't expose that the team was already requested for a review, + # so we wouldn't be able to avoid rerequesting reviews + # without saving some some extra state somewhere + + # We could also consider implementing a more advanced heuristic + # in the future that e.g. only pings one team member, + # but escalates to somebody else if that member doesn't respond in time. + gh api \ + --cache=1h \ + -H "Accept: application/vnd.github+json" \ + -H "X-GitHub-Api-Version: 2022-11-28" \ + "/orgs/$org/teams/$team/members" \ + --jq '.[].login' > "$tmp/team-members" + readarray -t members < "$tmp/team-members" + log "Team $handle has these members: ${members[*]}" + + for user in "${members[@]}"; do + users[${user,,}]= + done + else + # Everything else is a user + users[${handle,,}]= + fi done # Cannot request a review from the author @@ -68,7 +100,7 @@ for user in "${!users[@]}"; do fi done -if [[ "${#users[@]}" -gt 10 ]]; then +if [[ "${#users[@]}" -gt 15 ]]; then log "Too many reviewers (${!users[*]}), skipping review requests" exit 0 fi diff --git a/maintainers/maintainer-list.nix b/maintainers/maintainer-list.nix index cd87f8f97907..294d0d66463d 100644 --- a/maintainers/maintainer-list.nix +++ b/maintainers/maintainer-list.nix @@ -7991,7 +7991,7 @@ }; euxane = { name = "euxane"; - email = "r9uhdi.nixpkgs@euxane.net"; + email = "r9uhdi.nixpkgs@euxane.eu"; github = "pacien"; githubId = 1449319; }; diff --git a/nixos/doc/manual/release-notes/rl-2511.section.md b/nixos/doc/manual/release-notes/rl-2511.section.md index 2e73fe06aa0e..24ca7061f630 100644 --- a/nixos/doc/manual/release-notes/rl-2511.section.md +++ b/nixos/doc/manual/release-notes/rl-2511.section.md @@ -100,6 +100,8 @@ - [crowdsec](https://www.crowdsec.net/), a free, open-source and collaborative IPS. Available as [services.crowdsec](#opt-services.crowdsec.enable). +- [crowdsec-firewall-bouncer](https://www.crowdsec.net/), the CrowdSec Remediation Component for fetching new and old decisions from a CrowdSec API and adding them to a blocklist used by supported firewalls. Available as [services.crowdsec-firewall-bouncer](#opt-services.crowdsec-firewall-bouncer.enable). + - [tsidp](https://github.com/tailscale/tsidp), a simple OIDC / OAuth Identity Provider (IdP) server for your tailnet. Available as [services.tsidp](#opt-services.tsidp.enable). - [Newt](https://github.com/fosrl/newt), a fully user space WireGuard tunnel client and TCP/UDP proxy, designed to securely expose private resources controlled by Pangolin. Available as [services.newt](options.html#opt-services.newt.enable). diff --git a/nixos/modules/module-list.nix b/nixos/modules/module-list.nix index f66d92bf6f77..09a858a434db 100644 --- a/nixos/modules/module-list.nix +++ b/nixos/modules/module-list.nix @@ -1460,6 +1460,7 @@ ./services/security/certmgr.nix ./services/security/cfssl.nix ./services/security/clamav.nix + ./services/security/crowdsec-firewall-bouncer.nix ./services/security/crowdsec.nix ./services/security/e-imzo.nix ./services/security/endlessh-go.nix diff --git a/nixos/modules/services/security/crowdsec-firewall-bouncer.nix b/nixos/modules/services/security/crowdsec-firewall-bouncer.nix new file mode 100644 index 000000000000..5091ba4156a4 --- /dev/null +++ b/nixos/modules/services/security/crowdsec-firewall-bouncer.nix @@ -0,0 +1,390 @@ +{ + config, + pkgs, + lib, + ... +}: +let + cfg = config.services.crowdsec-firewall-bouncer; + format = pkgs.formats.yaml { }; +in +{ + options.services.crowdsec-firewall-bouncer = + let + inherit (lib) + types + mkOption + mkEnableOption + mkPackageOption + ; + in + { + enable = mkEnableOption "CrowdSec Firewall Bouncer"; + + package = mkPackageOption pkgs "crowdsec-firewall-bouncer" { }; + + createRulesets = mkOption { + type = types.bool; + description = '' + Whether to have the module create the appropriate firewall configuration + based on the bouncer settings. + You may disable this option to manually configure it. + ''; + default = true; + }; + + registerBouncer = { + enable = mkOption { + type = types.bool; + description = '' + Whether to automatically register the bouncer to the locally running + `crowdsec` service. + + When authenticating to an external CrowdSec API, you may use the + [](#opt-services.crowdsec-firewall-bouncer.secrets.apiKeyPath) option + instead. + ''; + default = config.services.crowdsec.enable; + defaultText = lib.literalExpression ''config.services.crowdsec.enable''; + }; + bouncerName = mkOption { + type = types.nonEmptyStr; + description = "Name to register the bouncer as to the CrowdSec API"; + default = "crowdsec-firewall-bouncer"; + }; + }; + + secrets = { + apiKeyPath = mkOption { + type = types.nullOr types.path; + description = '' + Path to the API key to authenticate with a local CrowdSec API. + + You need to call `cscli bouncers add ` to register + the bouncer and get this API key. + + When authenticating to the locally running `crowdsec` service, you may use the + [](#opt-services.crowdsec-firewall-bouncer.registerBouncer.enable) option instead. + ''; + default = null; + }; + }; + + settings = mkOption { + description = '' + Settings for the main CrowdSec Firewall Bouncer. + + Refer to the defaults at . + ''; + default = { }; + type = types.submodule { + freeformType = format.type; + options = { + mode = mkOption { + type = types.str; + description = "Firewall mode to use."; + default = if config.networking.nftables.enable then "nftables" else "iptables"; + defaultText = lib.literalExpression ''if config.networking.nftables.enable then "nftables" else "iptables"''; + }; + api_url = mkOption { + type = types.str; + description = "URL of the local API."; + example = "http://127.0.0.1:8080"; + default = "http://${config.services.crowdsec.settings.general.api.server.listen_uri}"; + defaultText = lib.literalExpression ''http://$\{config.services.crowdsec.settings.general.api.server.listen_uri}''; + }; + api_key = mkOption { + type = types.nullOr types.str; + description = '' + API key to authenticate with a local crowdsec API. + + You need to call `cscli bouncers add ` to register + the bouncer and get this API key. + + Setting this option will store this secret in the Nix store. + Instead, you should set the `services.crowdsec-firewall-bouncer.secrets.apiKeyPath` + option, which will read the value at runtime. + ''; + default = null; + }; + }; + }; + }; + }; + + config = lib.mkIf cfg.enable { + assertions = [ + { + assertion = + cfg.registerBouncer.enable || (cfg.secrets.apiKeyPath != null) || (cfg.settings.api_key != null); + message = '' + An API key must be set for the bouncer to be able to authenticate to a local crowdsec API. + + See the `registerBouncer.enable` and `secrets.apiKeyPath` options of + `services.crowdsec-firewall-bouncer` for more information. + ''; + } + { + assertion = !(cfg.registerBouncer.enable && (cfg.secrets.apiKeyPath != null)); + message = '' + The `registerBouncer.enable` and `secrets.apiKeyPath` options of + `services.crowdsec-firewall-bouncer` are mutually exclusive. + ''; + } + { + assertion = !(cfg.registerBouncer.enable && !config.services.crowdsec.enable); + message = '' + The `services.crowdsec-firewall-bouncer.registerBouncer.enable` option + requires the `crowdsec` service to be enabled. + ''; + } + { + assertion = !(cfg.settings.mode == "ipset" && cfg.createRulesets); + message = '' + The crowdsec-firewall-bouncer module is currently not able to configure the firewall in "ipset" mode. + + Either set the `services.crowdsec-firewall-bouncer.settings.mode` to "iptables" to leave the bouncer + manage the firewall configuration, or disable the `services.crowdsec-firewall-bouncer.createRulesets` + option and manually configure your firewall. + ''; + } + ]; + + # Default settings + services.crowdsec-firewall-bouncer.settings = { + update_frequency = lib.mkDefault "10s"; + log_mode = lib.mkDefault "stdout"; + log_level = lib.mkDefault "info"; + + # iptables-specific config + blacklists_ipv4 = lib.mkDefault "crowdsec-blacklists"; + blacklists_ipv6 = lib.mkDefault "crowdsec6-blacklists"; + iptables_chains = lib.mkDefault [ "INPUT" ]; + + # nftables-specific config + nftables = { + ipv4 = { + enabled = lib.mkDefault true; + set-only = lib.mkDefault true; + table = lib.mkDefault "crowdsec"; + chain = lib.mkDefault "crowdsec-chain"; + }; + ipv6 = { + enabled = lib.mkDefault true; + set-only = lib.mkDefault true; + table = lib.mkDefault "crowdsec6"; + chain = lib.mkDefault "crowdsec6-chain"; + }; + }; + }; + + # Use a placeholder for the api_key if it is to be read from a file at runtime + services.crowdsec-firewall-bouncer.settings.api_key = lib.mkIf ( + cfg.registerBouncer.enable || (cfg.secrets.apiKeyPath != null) + ) "@API_KEY_FILE@"; + + networking.nftables.tables = lib.mkIf (cfg.settings.mode == "nftables") { + "${cfg.settings.nftables.ipv4.table}" = + lib.mkIf + (cfg.createRulesets && cfg.settings.nftables.ipv4.enabled && cfg.settings.nftables.ipv4.set-only) + { + family = "ip"; + content = '' + set crowdsec-blacklists { + type ipv4_addr + flags timeout + } + + chain ${cfg.settings.nftables.ipv4.chain} { + type filter hook input priority filter; policy accept; + ip saddr @crowdsec-blacklists drop + } + ''; + }; + "${cfg.settings.nftables.ipv6.table}" = + lib.mkIf + (cfg.createRulesets && cfg.settings.nftables.ipv6.enabled && cfg.settings.nftables.ipv6.set-only) + { + family = "ip6"; + content = '' + set crowdsec6-blacklists { + type ipv6_addr + flags timeout + } + + chain ${cfg.settings.nftables.ipv6.chain} { + type filter hook input priority filter; policy accept; + ip6 saddr @crowdsec6-blacklists drop + } + ''; + }; + }; + + systemd.services = + let + apiKeyFile = "/var/lib/crowdsec-firewall-bouncer-register/api-key.cred"; + in + { + crowdsec-firewall-bouncer-register = lib.mkIf cfg.registerBouncer.enable rec { + description = "Register the CrowdSec Firewall Bouncer to the local CrowdSec service"; + wantedBy = [ "multi-user.target" ]; + after = [ "crowdsec.service" ]; + wants = after; + script = '' + cscli=/run/current-system/sw/bin/cscli + if $cscli bouncers list --output json | ${lib.getExe pkgs.jq} -e -- ${lib.escapeShellArg "any(.[]; .name == \"${cfg.registerBouncer.bouncerName}\")"} >/dev/null; then + # Bouncer already registered. Verify the API key is still present + if [ ! -f ${apiKeyFile} ]; then + echo "Bouncer registered but API key is not present" + exit 1 + fi + else + # Bouncer not registered + # Remove any previously saved API key + rm -f '${apiKeyFile}' + # Register the bouncer and save the new API key + if ! $cscli bouncers add --output raw -- ${lib.escapeShellArg cfg.registerBouncer.bouncerName} >${apiKeyFile}; then + # Failed to register the bouncer + rm ${apiKeyFile} + exit 1 + fi + fi + ''; + serviceConfig = { + Type = "oneshot"; + + # Run as crowdsec user to be able to use cscli + User = config.services.crowdsec.user; + Group = config.services.crowdsec.group; + + StateDirectory = "crowdsec-firewall-bouncer-register"; + + ReadWritePaths = [ + # Needs write permissions to add the bouncer + "/var/lib/crowdsec" + ]; + + DynamicUser = true; + LockPersonality = true; + PrivateDevices = true; + ProcSubset = "pid"; + ProtectClock = true; + ProtectControlGroups = true; + ProtectHome = true; + ProtectHostname = true; + ProtectKernelLogs = true; + ProtectKernelModules = true; + ProtectKernelTunables = true; + ProtectProc = "invisible"; + RestrictNamespaces = true; + RestrictRealtime = true; + SystemCallArchitectures = "native"; + + RestrictAddressFamilies = "none"; + CapabilityBoundingSet = [ "" ]; + SystemCallFilter = [ + "@system-service" + "~@privileged" + "~@resources" + ]; + UMask = "0077"; + }; + }; + + crowdsec-firewall-bouncer = + let + runtime-dir-name = "crowdsec-firewall-bouncer"; + final-config-file = "/run/${runtime-dir-name}/config.yaml"; + generateConfig = pkgs.writeShellScript "crowdsec-firewall-bouncer-config" '' + set -euo pipefail + umask 077 + + # Copy the template to the final location + cp ${format.generate "crowdsec-firewall-bouncer-config-template.yml" cfg.settings} ${final-config-file} + chmod 0600 ${final-config-file} + + # Replace the api_key placeholder with the secret + ${lib.getExe pkgs.replace-secret} '@API_KEY_FILE@' "$CREDENTIALS_DIRECTORY/API_KEY_FILE" ${final-config-file} + ''; + in + rec { + description = "CrowdSec Firewall Bouncer"; + wantedBy = [ "multi-user.target" ]; + after = [ "network.target" ] ++ (lib.optional config.services.crowdsec.enable "crowdsec.service"); + wants = after; + requires = lib.optional cfg.registerBouncer.enable "crowdsec-firewall-bouncer-register.service"; + + # When using iptables/ipset modes, the bouncer calls external binaries so they must be added to the path. + # For nftables mode, it does not depend on external binaries. + path = lib.optionals ((cfg.settings.mode == "iptables") || (cfg.settings.mode == "ipset")) [ + pkgs.iptables + pkgs.ipset + ]; + + serviceConfig = rec { + Type = "notify"; + ExecStartPre = [ + generateConfig + "${lib.getExe cfg.package} -c ${final-config-file} -t" + ]; + ExecStart = [ + "${lib.getExe cfg.package} -c ${final-config-file}" + ]; + + # Same as upstream + LimitNOFILE = 65536; + KillMode = "mixed"; + + # Load the api_key secret to be able to use it when generating the final config + LoadCredential = + if (cfg.registerBouncer.enable) then + "API_KEY_FILE:${apiKeyFile}" + else if (cfg.secrets.apiKeyPath != null) then + "API_KEY_FILE:${cfg.secrets.apiKeyPath}" + else + null; + + DynamicUser = true; + RuntimeDirectory = runtime-dir-name; + + LockPersonality = true; + PrivateDevices = true; + ProcSubset = "pid"; + ProtectClock = true; + ProtectControlGroups = true; + ProtectHome = true; + ProtectHostname = true; + ProtectKernelLogs = true; + ProtectKernelModules = true; + ProtectKernelTunables = true; + ProtectProc = "invisible"; + RestrictNamespaces = true; + RestrictRealtime = true; + SystemCallArchitectures = "native"; + + RestrictAddressFamilies = [ + "AF_NETLINK" + "AF_UNIX" + "AF_INET" + "AF_INET6" + ]; + AmbientCapabilities = [ + # Needed to be able to manipulate the rulesets + "CAP_NET_ADMIN" + ]; + CapabilityBoundingSet = AmbientCapabilities; + SystemCallFilter = [ + "@system-service" + "~@privileged" + "~@resources" + ]; + UMask = "0077"; + }; + }; + }; + }; + + meta = { + maintainers = with lib.maintainers; [ nicomem ]; + }; +} diff --git a/nixos/modules/services/web-apps/actual.nix b/nixos/modules/services/web-apps/actual.nix index 1ece9f7f04f1..0e0bd29c4236 100644 --- a/nixos/modules/services/web-apps/actual.nix +++ b/nixos/modules/services/web-apps/actual.nix @@ -2,6 +2,7 @@ lib, pkgs, config, + utils, ... }: let @@ -16,7 +17,6 @@ let ; cfg = config.services.actual; - configFile = formatType.generate "config.json" cfg.settings; dataDir = "/var/lib/actual"; formatType = pkgs.formats.json { }; @@ -32,19 +32,12 @@ in description = "Whether to open the firewall for the specified port."; }; - environmentFile = mkOption { - type = types.nullOr types.path; - default = null; - description = '' - Environment file for specifying additional settings such as secrets. - - See . - ''; - }; - settings = mkOption { default = { }; - description = "Server settings, refer to [the documentation](https://actualbudget.org/docs/config/) for available options."; + description = '' + Server settings, refer to [the documentation](https://actualbudget.org/docs/config/) for available options. + You can specify secret values in this configuration by setting `somevalue._secret = "/path/to/file"` instead of setting `somevalue` directly. + ''; type = types.submodule { freeformType = formatType.type; @@ -78,15 +71,21 @@ in description = "Actual server, a local-first personal finance app"; after = [ "network.target" ]; wantedBy = [ "multi-user.target" ]; - environment.ACTUAL_CONFIG_PATH = configFile; + environment.ACTUAL_CONFIG_PATH = "/run/actual/config.json"; + + preStart = '' + # Generate config including secret values. + ${utils.genJqSecretsReplacementSnippet cfg.settings "/run/actual/config.json"} + ''; + serviceConfig = { ExecStart = getExe cfg.package; DynamicUser = true; User = "actual"; Group = "actual"; StateDirectory = "actual"; + RuntimeDirectory = "actual"; WorkingDirectory = dataDir; - EnvironmentFile = cfg.environmentFile; LimitNOFILE = "1048576"; PrivateTmp = true; PrivateDevices = true; diff --git a/nixos/tests/xfce.nix b/nixos/tests/xfce.nix index cdd1f3ffc676..ae203c5ca26d 100644 --- a/nixos/tests/xfce.nix +++ b/nixos/tests/xfce.nix @@ -21,6 +21,7 @@ environment.systemPackages = [ pkgs.xfce.xfce4-whiskermenu-plugin ]; programs.thunar.plugins = [ pkgs.xfce.thunar-archive-plugin ]; + programs.ydotool.enable = true; }; enableOCR = true; @@ -44,8 +45,9 @@ with subtest("Check if Xfce components actually start"): machine.wait_for_window("xfce4-panel") machine.wait_for_window("Desktop") - for i in ["xfwm4", "xfsettingsd", "xfdesktop", "xfce4-screensaver", "xfce4-notifyd", "xfconfd"]: - machine.wait_until_succeeds(f"pgrep -f {i}") + for i in ["xfwm4", "xfsettingsd", "xfdesktop", "xfce4-notifyd", "xfconfd"]: + machine.wait_until_succeeds(f"pgrep {i}") + machine.wait_until_succeeds("pgrep -xf xfce4-screensaver") with subtest("Open whiskermenu"): machine.succeed("su - ${user.name} -c 'DISPLAY=:0 ${bus} xfconf-query -c xfce4-panel -p /plugins/plugin-1 -t string -s whiskermenu -n >&2 &'") @@ -63,6 +65,17 @@ machine.succeed("su - ${user.name} -c 'DISPLAY=:0 xfce4-terminal >&2 &'") machine.wait_for_window("Terminal") + with subtest("Lock the screen"): + machine.succeed("su - ${user.name} -c '${bus} xflock4 >&2 &'") + machine.wait_until_succeeds("su - ${user.name} -c '${bus} xfce4-screensaver-command -q' | grep 'The screensaver is active'") + machine.sleep(5) + machine.succeed("ydotool click 0xC0") + machine.wait_for_text("${user.description}|Unlock") + machine.screenshot("screensaver") + machine.send_chars("${user.password}\n", delay=0.2) + machine.wait_until_succeeds("su - ${user.name} -c '${bus} xfce4-screensaver-command -q' | grep 'The screensaver is inactive'") + machine.sleep(2) + with subtest("Open Thunar"): machine.succeed("su - ${user.name} -c 'DISPLAY=:0 thunar >&2 &'") machine.wait_for_window("Thunar") diff --git a/pkgs/applications/blockchains/bitcoin-knots/default.nix b/pkgs/applications/blockchains/bitcoin-knots/default.nix index 6d934130acd1..f4c67304d565 100644 --- a/pkgs/applications/blockchains/bitcoin-knots/default.nix +++ b/pkgs/applications/blockchains/bitcoin-knots/default.nix @@ -10,6 +10,7 @@ wrapQtAppsHook ? null, boost, libevent, + libsodium, zeromq, zlib, db48, @@ -67,6 +68,7 @@ stdenv.mkDerivation (finalAttrs: { buildInputs = [ boost libevent + libsodium zeromq zlib ] diff --git a/pkgs/applications/networking/cluster/terraform-providers/providers.json b/pkgs/applications/networking/cluster/terraform-providers/providers.json index 093947426af2..eb518b76241a 100644 --- a/pkgs/applications/networking/cluster/terraform-providers/providers.json +++ b/pkgs/applications/networking/cluster/terraform-providers/providers.json @@ -949,13 +949,13 @@ "vendorHash": "sha256-OAd8SeTqTrH0kMoM2LsK3vM2PI23b3gl57FaJYM9hM0=" }, "newrelic_newrelic": { - "hash": "sha256-/vHE+Eys773WyYMDe7xG3p0pgKvRc9U73s4jSDijNxY=", + "hash": "sha256-1OpvSayWq194591u/z9oHz80ZmPA9fSZpKSBwDHL/tk=", "homepage": "https://registry.terraform.io/providers/newrelic/newrelic", "owner": "newrelic", "repo": "terraform-provider-newrelic", - "rev": "v3.73.0", + "rev": "v3.74.0", "spdx": "MPL-2.0", - "vendorHash": "sha256-45psSf69IetY0o8LjBDEv2GnOxaOzaQcPCnV2YHPXGs=" + "vendorHash": "sha256-7zUUV3cqVesItNnE/EcO5/l+nafV04JdoNkmTxnulio=" }, "ns1-terraform_ns1": { "hash": "sha256-S0ji/gZsbMTgug7DwPODAcPx3IfRaw1JHYPJ6V+tqeM=", diff --git a/pkgs/applications/video/anilibria-winmaclinux/default.nix b/pkgs/applications/video/anilibria-winmaclinux/default.nix index 5b1fa114902d..6e4b6d9f18eb 100644 --- a/pkgs/applications/video/anilibria-winmaclinux/default.nix +++ b/pkgs/applications/video/anilibria-winmaclinux/default.nix @@ -21,13 +21,13 @@ mkDerivation rec { pname = "anilibria-winmaclinux"; - version = "2.2.31"; + version = "2.2.32"; src = fetchFromGitHub { owner = "anilibria"; repo = "anilibria-winmaclinux"; rev = version; - hash = "sha256-czLEYPz+5vXHisXexzRXLhwN4onka31hn69F4MaSnCs="; + hash = "sha256-Wxzv1iLJ+OWw+g6ndBX36AR2v9cSu2uZysegz97+XaM="; }; sourceRoot = "${src.name}/src"; diff --git a/pkgs/by-name/am/amp-cli/package-lock.json b/pkgs/by-name/am/amp-cli/package-lock.json index a177c3c17851..7a393abfde79 100644 --- a/pkgs/by-name/am/amp-cli/package-lock.json +++ b/pkgs/by-name/am/amp-cli/package-lock.json @@ -5,7 +5,7 @@ "packages": { "": { "dependencies": { - "@sourcegraph/amp": "^0.0.1761583653-gd8c2df" + "@sourcegraph/amp": "^0.0.1762056193-g37ad2e" } }, "node_modules/@napi-rs/keyring": { @@ -228,9 +228,9 @@ } }, "node_modules/@sourcegraph/amp": { - "version": "0.0.1761583653-gd8c2df", - "resolved": "https://registry.npmjs.org/@sourcegraph/amp/-/amp-0.0.1761583653-gd8c2df.tgz", - "integrity": "sha512-/sAPMVQkj3sLtuYfv4GAXRBfqrWPHcMXbeWXXqW0+i8GKMsrMIenawwkEzQdCoTH94eZYeS8JlBPde3YFsdDOA==", + "version": "0.0.1762056193-g37ad2e", + "resolved": "https://registry.npmjs.org/@sourcegraph/amp/-/amp-0.0.1762056193-g37ad2e.tgz", + "integrity": "sha512-dWhc7ajnw1QGCYwrOGwCbpyzedf5n2RoTCM97ibpzgpphDLCdyGTXh2XTC6mrxM2CNQLp5jJaWxvcDk9nM80Vg==", "dependencies": { "@napi-rs/keyring": "1.1.9" }, diff --git a/pkgs/by-name/am/amp-cli/package.nix b/pkgs/by-name/am/amp-cli/package.nix index d981668628e3..0dfeb0d3eac1 100644 --- a/pkgs/by-name/am/amp-cli/package.nix +++ b/pkgs/by-name/am/amp-cli/package.nix @@ -9,11 +9,11 @@ buildNpmPackage (finalAttrs: { pname = "amp-cli"; - version = "0.0.1761583653-gd8c2df"; + version = "0.0.1762056193-g37ad2e"; src = fetchzip { url = "https://registry.npmjs.org/@sourcegraph/amp/-/amp-${finalAttrs.version}.tgz"; - hash = "sha256-Q6iBVtSIXoy6r+9/s3GefLq5c9SFRSQoBxUjBlg/wh8="; + hash = "sha256-so/nlX4N9qhNLsK0OllmpfiqzyEBtPrt7KD/MoAChGc="; }; postPatch = '' @@ -45,7 +45,7 @@ buildNpmPackage (finalAttrs: { chmod +x bin/amp-wrapper.js ''; - npmDepsHash = "sha256-n8dRIJPTFFhS3aQQKKRdqYcEeHxfpU9XGbeV+2XAVeY="; + npmDepsHash = "sha256-xhN5XJs8E7yCRQWRPlH9iZyh5FocUjFMto5QweaV8aI="; propagatedBuildInputs = [ ripgrep diff --git a/pkgs/by-name/ba/backrest/package.nix b/pkgs/by-name/ba/backrest/package.nix index 56315431180a..2ab3f13341b0 100644 --- a/pkgs/by-name/ba/backrest/package.nix +++ b/pkgs/by-name/ba/backrest/package.nix @@ -14,13 +14,13 @@ }: let pname = "backrest"; - version = "1.9.2"; + version = "1.10.1"; src = fetchFromGitHub { owner = "garethgeorge"; repo = "backrest"; tag = "v${version}"; - hash = "sha256-3lAWViC9K34R8la/z57kjGJmMmletGd8pJ1dDt+BeKQ="; + hash = "sha256-8WWs7XEVKAc/XmeL+dsw25azfLjUbHKp2MsB6Be14VE="; }; frontend = stdenv.mkDerivation (finalAttrs: { @@ -64,7 +64,7 @@ buildGoModule { internal/resticinstaller/resticinstaller.go ''; - vendorHash = "sha256-oycV8JAJQF/PNc7mmYGzkZbpG8pMwxThmuys9e0+hcc="; + vendorHash = "sha256-cYqK/sddLI38K9bzCpnomcZOYbSRDBOEru4Y26rBLFw="; nativeBuildInputs = [ gzip diff --git a/pkgs/by-name/bi/bitrise/package.nix b/pkgs/by-name/bi/bitrise/package.nix index 09139984a44e..0241eb4d667c 100644 --- a/pkgs/by-name/bi/bitrise/package.nix +++ b/pkgs/by-name/bi/bitrise/package.nix @@ -6,13 +6,13 @@ }: buildGoModule rec { pname = "bitrise"; - version = "2.34.5"; + version = "2.34.6"; src = fetchFromGitHub { owner = "bitrise-io"; repo = "bitrise"; rev = "v${version}"; - hash = "sha256-QsGF5lDnY55OGdFagGJfXcq9/2P6qzmoHx64ijOkRfo="; + hash = "sha256-wA+IknAOkVxTwBohw8D4suksENoWymqPJycbfx6cFYQ="; }; # many tests rely on writable $HOME/.bitrise and require network access diff --git a/pkgs/by-name/cu/cursor-cli/package.nix b/pkgs/by-name/cu/cursor-cli/package.nix index 55d794f0ac5c..bdb8015ce19e 100644 --- a/pkgs/by-name/cu/cursor-cli/package.nix +++ b/pkgs/by-name/cu/cursor-cli/package.nix @@ -9,26 +9,26 @@ let inherit (stdenv) hostPlatform; sources = { x86_64-linux = fetchurl { - url = "https://downloads.cursor.com/lab/2025.10.22-f894c20/linux/x64/agent-cli-package.tar.gz"; - hash = "sha256-bblnHWrPXJ9UmStfjUis1jLYLyawRchF0+UBMmPHy7M="; + url = "https://downloads.cursor.com/lab/2025.10.28-0a91dc2/linux/x64/agent-cli-package.tar.gz"; + hash = "sha256-mZ0T7rrKzwvaNUbrHBy3XO04vZSO6RQ4RmJmrdfaoJA="; }; aarch64-linux = fetchurl { - url = "https://downloads.cursor.com/lab/2025.10.22-f894c20/linux/arm64/agent-cli-package.tar.gz"; - hash = "sha256-MnL1TLI7ggi9qaicUN//8o3EJoCPd0gF9KKfekIhUM0="; + url = "https://downloads.cursor.com/lab/2025.10.28-0a91dc2/linux/arm64/agent-cli-package.tar.gz"; + hash = "sha256-bchHYPQ0O/0YWiPdj3wnq43p/fKFoP4KXpeSVWpLYpE="; }; x86_64-darwin = fetchurl { - url = "https://downloads.cursor.com/lab/2025.10.22-f894c20/darwin/x64/agent-cli-package.tar.gz"; - hash = "sha256-UEQyHEopNKf5uDUlZVzTESXVi8e2wHp83cD01diAISY="; + url = "https://downloads.cursor.com/lab/2025.10.28-0a91dc2/darwin/x64/agent-cli-package.tar.gz"; + hash = "sha256-PWx5QAs84gWNOHYZL20uFnW+m4rApRT6g4LtabjL+lw="; }; aarch64-darwin = fetchurl { - url = "https://downloads.cursor.com/lab/2025.10.22-f894c20/darwin/arm64/agent-cli-package.tar.gz"; - hash = "sha256-18u5K/4Mc9+R32umaBWD5chgMoatkd/ZSMCiPElmPJU="; + url = "https://downloads.cursor.com/lab/2025.10.28-0a91dc2/darwin/arm64/agent-cli-package.tar.gz"; + hash = "sha256-VW76Lx2VKspiGkphp74ib4+F5FCdu8793f+xvD67OpM="; }; }; in stdenv.mkDerivation { pname = "cursor-cli"; - version = "0-unstable-2025-10-22"; + version = "0-unstable-2025-10-28"; src = sources.${hostPlatform.system}; diff --git a/pkgs/by-name/do/docker-language-server/package.nix b/pkgs/by-name/do/docker-language-server/package.nix index c08d016dfcc2..06d64fb121dd 100644 --- a/pkgs/by-name/do/docker-language-server/package.nix +++ b/pkgs/by-name/do/docker-language-server/package.nix @@ -8,16 +8,16 @@ buildGoModule rec { pname = "docker-language-server"; - version = "0.16.0"; + version = "0.20.1"; src = fetchFromGitHub { owner = "docker"; repo = "docker-language-server"; tag = "v${version}"; - hash = "sha256-P3DwlCjQllFtf05ssXYNraQFGEEzChSE5eJvcODdF6Q="; + hash = "sha256-OSAySCTK2temrVxmkRnrl5YWVbmkp8DRlXFVxTzEW3Q="; }; - vendorHash = "sha256-xvRHxi7aem88mrmdAmSyRNtBUSZD4rjUut2VjPeoejg="; + vendorHash = "sha256-ztA+/4l180UKTKrsqTyysDcD4oQSDgnBYUaiKDF6LvI="; nativeCheckInputs = [ docker diff --git a/pkgs/by-name/fa/fastd-exporter/package.nix b/pkgs/by-name/fa/fastd-exporter/package.nix index 229bb7ee2caf..df9a6ccfb567 100644 --- a/pkgs/by-name/fa/fastd-exporter/package.nix +++ b/pkgs/by-name/fa/fastd-exporter/package.nix @@ -12,7 +12,7 @@ buildGoModule { owner = "freifunk-darmstadt"; repo = "fastd-exporter"; rev = "374e4334af6661f4c91a3e83bf7ce071a2a72eca"; - sha256 = "sha256-0oU4+9G19XP5qtGdcfMz08T04hjcoXX/O+FkaUPxzXE="; + hash = "sha256-0oU4+9G19XP5qtGdcfMz08T04hjcoXX/O+FkaUPxzXE="; }; vendorHash = "sha256-r0W64dct6XWa9sIrzy0UdyoMw+kAq73Qc/QchmsYZkY="; diff --git a/pkgs/by-name/fa/fastmail-desktop/darwin.nix b/pkgs/by-name/fa/fastmail-desktop/darwin.nix new file mode 100644 index 000000000000..6e815849081c --- /dev/null +++ b/pkgs/by-name/fa/fastmail-desktop/darwin.nix @@ -0,0 +1,27 @@ +{ + pname, + version, + src, + passthru, + meta, + stdenvNoCC, +}: +stdenvNoCC.mkDerivation { + inherit + pname + version + src + passthru + meta + ; + + installPhase = '' + mkdir -p $out/Applications + cp -R Fastmail.app $out/Applications/ + ''; + + dontBuild = true; + + # Fastmail is notarized + dontFixup = true; +} diff --git a/pkgs/by-name/fa/fastmail-desktop/linux.nix b/pkgs/by-name/fa/fastmail-desktop/linux.nix new file mode 100644 index 000000000000..63d8fbeb2ef9 --- /dev/null +++ b/pkgs/by-name/fa/fastmail-desktop/linux.nix @@ -0,0 +1,84 @@ +{ + pname, + version, + src, + passthru, + meta, + lib, + stdenvNoCC, + appimageTools, + asar, + autoPatchelfHook, + makeWrapper, + electron, + libXScrnSaver, + libXtst, + libappindicator, + libgcc, + musl, + vips, +}: +let + appimageContents = appimageTools.extract { inherit pname version src; }; +in +stdenvNoCC.mkDerivation (finalAttrs: { + inherit pname version passthru; + + dontUnpack = true; + dontBuild = true; + + strictDeps = true; + + nativeBuildInputs = [ + asar + autoPatchelfHook + makeWrapper + ]; + + buildInputs = [ + libgcc + musl + vips + ]; + + libPath = lib.makeLibraryPath [ + libXScrnSaver + libXtst + libappindicator + ]; + + installPhase = '' + runHook preInstall + + mkdir -p "$out/opt" + cp -r --no-preserve=mode "${appimageContents}/resources" "$out/opt/fastmail" + asar extract "$out/opt/fastmail/app.asar" "$out/opt/fastmail/app.asar.unpacked" + rm "$out/opt/fastmail/app.asar" + + install -D "${appimageContents}/production.desktop" "$out/share/applications/fastmail.desktop" + substituteInPlace "$out/share/applications/fastmail.desktop" \ + --replace-fail "Exec=AppRun --no-sandbox %U" "Exec=fastmail" \ + --replace-fail "Icon=production" "Icon=fastmail" \ + + for res in 16 24 32 48 64 128 256 512 1024; do + resdir="''${res}x''${res}" + mkdir -p "$out/share/icons/hicolor/$resdir/apps" + cp -r --no-preserve=mode \ + "${appimageContents}/usr/share/icons/hicolor/$resdir/apps/production.png" \ + "$out/share/icons/hicolor/$resdir/apps/fastmail.png" + done + + makeWrapper "${electron}/bin/electron" "$out/bin/fastmail" \ + --add-flags "$out/opt/fastmail/app.asar.unpacked" \ + --add-flags "\''${NIXOS_OZONE_WL:+\''${WAYLAND_DISPLAY:+--ozone-platform-hint=auto --enable-wayland-ime=true --wayland-text-input-version=3}}" \ + --prefix LD_LIBRARY_PATH : ${finalAttrs.libPath}:$out/opt/fastmail \ + --set-default ELECTRON_IS_DEV 0 \ + --inherit-argv0 + + runHook postInstall + ''; + + meta = meta // { + mainProgram = "fastmail"; + }; +}) diff --git a/pkgs/by-name/fa/fastmail-desktop/package.nix b/pkgs/by-name/fa/fastmail-desktop/package.nix index 5e0bb16ac1dc..531fdce45e84 100644 --- a/pkgs/by-name/fa/fastmail-desktop/package.nix +++ b/pkgs/by-name/fa/fastmail-desktop/package.nix @@ -1,34 +1,33 @@ { lib, + callPackage, stdenvNoCC, + fetchurl, fetchzip, }: -stdenvNoCC.mkDerivation (finalAttrs: { +let + inherit (stdenvNoCC.hostPlatform) isDarwin system; + + sources = import ./sources.nix { inherit fetchurl fetchzip; }; +in +callPackage (if isDarwin then ./darwin.nix else ./linux.nix) { pname = "fastmail-desktop"; - version = "1.0.0"; + inherit (sources.${system} or (throw "Unsupported system: ${system}")) version src; - src = fetchzip { - url = "https://dl.fastmailcdn.com/desktop/production/mac/arm64/Fastmail-${finalAttrs.version}-arm64-mac.zip"; - hash = "sha256-wIWU0F08wEQeLjbZz2LqahfyeOfowC+dDQkeMZI6gbk="; - stripRoot = false; - }; - - installPhase = '' - mkdir -p $out/Applications - cp -R Fastmail.app $out/Applications/ - ''; - - dontBuild = true; - - # Fastmail is notarized - dontFixup = true; + passthru.updateScript = ./update.sh; meta = { description = "Dedicated desktop app for Fastmail"; homepage = "https://www.fastmail.com/blog/desktop-app/"; license = lib.licenses.unfree; - sourceProvenance = with lib.sourceTypes; [ binaryNativeCode ]; - maintainers = [ lib.maintainers.Enzime ]; - platforms = [ "aarch64-darwin" ]; + sourceProvenance = [ lib.sourceTypes.binaryNativeCode ]; + maintainers = [ + lib.maintainers.Enzime + lib.maintainers.nekowinston + ]; + platforms = [ + "aarch64-darwin" + "x86_64-linux" + ]; }; -}) +} diff --git a/pkgs/by-name/fa/fastmail-desktop/sources.nix b/pkgs/by-name/fa/fastmail-desktop/sources.nix new file mode 100644 index 000000000000..da373f653e94 --- /dev/null +++ b/pkgs/by-name/fa/fastmail-desktop/sources.nix @@ -0,0 +1,20 @@ +# Generated by ./update.sh - do not update manually! +# Last updated: 2025-10-30 +{ fetchurl, fetchzip }: +{ + aarch64-darwin = { + version = "1.0.3"; + src = fetchzip { + url = "https://dl.fastmailcdn.com/desktop/production/mac/arm64/Fastmail-1.0.3-arm64-mac.zip"; + hash = "sha512-lqJj0tTwOJx1jzzXtlKOOduUEtSgVHpQCM5WkbXjmOh2OejLRcdJ1Y9CxvZJGSPBGWrErKzytMOB8QmJ1BkIdw=="; + stripRoot = false; + }; + }; + x86_64-linux = { + version = "1.0.3"; + src = fetchurl { + url = "https://dl.fastmailcdn.com/desktop/production/linux/x64/Fastmail-1.0.3.AppImage"; + hash = "sha512-L+h0GHAAlZndB4Q5Z7GiHuZqv1kTF5yCAJYYb9tPXnHfdcrwHvfBRnixEnVPPia46rp2IJ56z4ZS8RSut3ATFQ=="; + }; + }; +} diff --git a/pkgs/by-name/fa/fastmail-desktop/update.sh b/pkgs/by-name/fa/fastmail-desktop/update.sh new file mode 100755 index 000000000000..52c07e300a96 --- /dev/null +++ b/pkgs/by-name/fa/fastmail-desktop/update.sh @@ -0,0 +1,41 @@ +#!/usr/bin/env nix-shell +#! nix-shell -i bash --pure -p cacert curl yq nix + +set -euo pipefail + +cd "$(readlink -e "$(dirname "${BASH_SOURCE[0]}")")" + +x86_64_linux_info=$(curl -fsS "https://dl.fastmailcdn.com/desktop/production/linux/x64/latest-linux.yml") +aarch64_darwin_info=$(curl -fsS "https://dl.fastmailcdn.com/desktop/production/mac/arm64/latest-mac.yml") + +x86_64_linux_version=$(yq -r '.version' <<<"$x86_64_linux_info") +aarch64_darwin_version=$(yq -r '.version' <<<"$aarch64_darwin_info") + +x86_64_linux_url="https://dl.fastmailcdn.com/desktop/production/linux/x64/$(yq -r '.path' <<<"$x86_64_linux_info")" +aarch64_darwin_url="https://dl.fastmailcdn.com/desktop/production/mac/arm64/$(yq -r '.path' <<<"$aarch64_darwin_info")" + +x86_64_linux_hash=$(nix-hash --type sha512 --to-sri "$(yq -r '.sha512' <<<"$x86_64_linux_info")") +aarch64_darwin_hash=$(nix-hash --type sha512 --to-sri "$(yq -r '.sha512' <<<"$aarch64_darwin_info")") + +cat >sources.nix < CONFIG_KUNIT should not be enabled in a production environment. Enabling KUnit disables Kernel Address-Space Layout Randomization (KASLR), and tests may affect the state of the kernel in ways not suitable for production. # https://www.kernel.org/doc/html/latest/dev-tools/kunit/start.html - KUNIT = whenAtLeast "5.5" no; + KUNIT = no; # Set system time from RTC on startup and resume RTC_HCTOSYS = option yes; @@ -1418,7 +1400,7 @@ let # Enable generic kernel watch queues # See https://docs.kernel.org/core-api/watch_queue.html - WATCH_QUEUE = whenAtLeast "5.8" yes; + WATCH_QUEUE = yes; } // lib.optionalAttrs @@ -1437,7 +1419,7 @@ let || isPower || isS390 || isx86 - || (lib.versionAtLeast version "5.7" && isAarch64) + || isAarch64 || (lib.versionAtLeast version "6.11" && isRiscV) ) yes; HOTPLUG_CPU = yes; @@ -1458,8 +1440,7 @@ let CROS_EC_I2C = module; CROS_EC_SPI = module; CROS_KBD_LED_BACKLIGHT = module; - MFD_CROS_EC = whenOlder "5.10" module; - TCG_TIS_SPI_CR50 = whenAtLeast "5.5" yes; + TCG_TIS_SPI_CR50 = yes; } // lib.optionalAttrs @@ -1521,7 +1502,7 @@ let CHROMEOS_PSTORE = module; # Enable x86 resource control - X86_CPU_RESCTRL = whenAtLeast "5.0" yes; + X86_CPU_RESCTRL = yes; # Enable TSX on CPUs where it's not vulnerable X86_INTEL_TSX_MODE_AUTO = yes; diff --git a/pkgs/os-specific/linux/kernel/kernels-org.json b/pkgs/os-specific/linux/kernel/kernels-org.json index 5dc249ac5b4c..bcbd01d44244 100644 --- a/pkgs/os-specific/linux/kernel/kernels-org.json +++ b/pkgs/os-specific/linux/kernel/kernels-org.json @@ -20,18 +20,18 @@ "lts": true }, "6.6": { - "version": "6.6.115", - "hash": "sha256:0iwhzlrqcw9hzr21gn0pmsjix0d022a7g38vszx4jsqgimgc160a", + "version": "6.6.116", + "hash": "sha256:07d5629579apc1d8yb0ki226iyb5n3lwp1yw0p189qlvq919g9d9", "lts": true }, "6.12": { - "version": "6.12.56", - "hash": "sha256:15pclwn3nbwccdfwcqd3lkmdxwpjkmadhj63acqbzxsjycm2nhsm", + "version": "6.12.57", + "hash": "sha256:06jlsawz1wgk13gyxphkglb8a4iiwg0vg5hrfc7bj1s6gk1s2p0n", "lts": true }, "6.17": { - "version": "6.17.6", - "hash": "sha256:17662dpl1rd24n20ihb1fsf66c8n3r6x1a24c6sanj1ld5mvrkwf", + "version": "6.17.7", + "hash": "sha256:03lxl2p8hvi4hdzbf72v3xh8yigr58826dmy6rqxbq9r8h6ymwnx", "lts": false } } diff --git a/pkgs/servers/nextcloud/packages/31.json b/pkgs/servers/nextcloud/packages/31.json index 89d4f58322d4..0c4a2d4ba82d 100644 --- a/pkgs/servers/nextcloud/packages/31.json +++ b/pkgs/servers/nextcloud/packages/31.json @@ -30,9 +30,9 @@ ] }, "collectives": { - "hash": "sha256-vWPT3FBSZlgA1z1zH1o1Kpd9JOmt2Ykfh3JMtMLWTjI=", - "url": "https://github.com/nextcloud/collectives/releases/download/v3.2.1/collectives-3.2.1.tar.gz", - "version": "3.2.1", + "hash": "sha256-ezFo8Vv8qFNzW9ZevcOmZdKBtmpDY6SpRqX4R/2UT1E=", + "url": "https://github.com/nextcloud/collectives/releases/download/v3.2.4/collectives-3.2.4.tar.gz", + "version": "3.2.4", "description": "Collectives is a Nextcloud App for activist and community projects to organize together.\nCome and gather in collectives to build shared knowledge.\n\n* ๐Ÿ‘ฅ **Collective and non-hierarchical workflow by heart**: Collectives are\n tied to a [Nextcloud Team](https://github.com/nextcloud/circles) and\n owned by the collective.\n* ๐Ÿ“ **Collaborative page editing** like known from Etherpad thanks to the\n [Text app](https://github.com/nextcloud/text).\n* ๐Ÿ”ค **Well-known [Markdown](https://en.wikipedia.org/wiki/Markdown) syntax**\n for page formatting.\n\n## Installation\n\nIn your Nextcloud instance, simply navigate to **ยปAppsยซ**, find the\n**ยปTeamsยซ** and **ยปCollectivesยซ** apps and enable them.", "homepage": "https://github.com/nextcloud/collectives", "licenses": [ @@ -40,9 +40,9 @@ ] }, "contacts": { - "hash": "sha256-J5ce01iRxpx4g24W5NAt7PgNX2hDjmA9VUzQAkLUrFE=", - "url": "https://github.com/nextcloud-releases/contacts/releases/download/v7.3.4/contacts-v7.3.4.tar.gz", - "version": "7.3.4", + "hash": "sha256-aViRCE48yy52yz7xSVlNKR6yFCVdu9hfjysL81QjazU=", + "url": "https://github.com/nextcloud-releases/contacts/releases/download/v7.3.5/contacts-v7.3.5.tar.gz", + "version": "7.3.5", "description": "The Nextcloud contacts app is a user interface for Nextcloud's CardDAV server. Easily sync contacts from various devices with your Nextcloud and edit them online.\n\n* ๐Ÿš€ **Integration with other Nextcloud apps!** Currently Mail and Calendar โ€“ more to come.\n* ๐ŸŽ‰ **Never forget a birthday!** You can sync birthdays and other recurring events with your Nextcloud Calendar.\n* ๐Ÿ‘ฅ **Sharing of Adressbooks!** You want to share your contacts with your friends or coworkers? No problem!\n* ๐Ÿ™ˆ **Weโ€™re not reinventing the wheel!** Based on the great and open SabreDAV library.", "homepage": "https://github.com/nextcloud/contacts#readme", "licenses": [ @@ -50,9 +50,9 @@ ] }, "cookbook": { - "hash": "sha256-pdmltxubvC2+h5U5edTB8X5M8WW+wBShIEpkbR0yaQ0=", - "url": "https://github.com/christianlupus-nextcloud/cookbook-releases/releases/download/v0.11.4/cookbook-0.11.4.tar.gz", - "version": "0.11.4", + "hash": "sha256-Bw5Oga5zawiicIR9tOLSflK0258Uy7q/9zJsXS5Ggd4=", + "url": "https://github.com/christianlupus-nextcloud/cookbook-releases/releases/download/v0.11.5/cookbook-0.11.5.tar.gz", + "version": "0.11.5", "description": "A library for all your recipes. It uses JSON files following the schema.org recipe format. To add a recipe to the collection, you can paste in the URL of the recipe, and the provided web page will be parsed and downloaded to whichever folder you specify in the app settings.", "homepage": "https://github.com/nextcloud/cookbook/", "licenses": [ @@ -140,9 +140,9 @@ ] }, "gpoddersync": { - "hash": "sha256-xMSo5D3w/qIMxLclSTmBPVBHwNkyTbluqlXWtdbLUYk=", - "url": "https://github.com/thrillfall/nextcloud-gpodder/releases/download/3.13.2/gpoddersync.tar.gz", - "version": "3.13.1", + "hash": "sha256-EQVs1fe0ierjqFZ5+KVc1Yj67zrwjLBAzY5A+QsC7AU=", + "url": "https://github.com/thrillfall/nextcloud-gpodder/releases/download/3.13.2r/gpoddersync.tar.gz", + "version": "3.13.2", "description": "Expose GPodder API to sync podcast consumer apps like AntennaPod", "homepage": "https://github.com/thrillfall/nextcloud-gpodder", "licenses": [ @@ -230,9 +230,9 @@ ] }, "news": { - "hash": "sha256-K93swGriEwm1zBq9H7F4P2fHmTanYddFARfQp456bds=", - "url": "https://github.com/nextcloud/news/releases/download/27.0.1/news.tar.gz", - "version": "27.0.1", + "hash": "sha256-bKIEeRVmDoDjab8dusdG+q7Ms/gaOUFUyCH1C1pKJ04=", + "url": "https://github.com/nextcloud/news/releases/download/27.1.0/news.tar.gz", + "version": "27.1.0", "description": "๐Ÿ“ฐ A RSS/Atom Feed reader App for Nextcloud\n\n- ๐Ÿ“ฒ Synchronize your feeds with multiple mobile or desktop [clients](https://nextcloud.github.io/news/clients/)\n- ๐Ÿ”„ Automatic updates of your news feeds\n- ๐Ÿ†“ Free and open source under AGPLv3, no ads or premium functions\n\n**System Cron is currently required for this app to work**\n\nRequirements can be found [here](https://nextcloud.github.io/news/install/#dependencies)\n\nThe Changelog is available [here](https://github.com/nextcloud/news/blob/master/CHANGELOG.md)\n\nCreate a [bug report](https://github.com/nextcloud/news/issues/new/choose)\n\nCreate a [feature request](https://github.com/nextcloud/news/discussions/new)\n\nReport a [feed issue](https://github.com/nextcloud/news/discussions/new)", "homepage": "https://github.com/nextcloud/news", "licenses": [ @@ -360,9 +360,9 @@ ] }, "sociallogin": { - "hash": "sha256-zuzQKtU+sEEYhBZ4UMfY1eMSsDfe7o/ymWYv2SJBiHw=", - "url": "https://github.com/zorn-v/nextcloud-social-login/releases/download/v6.2.2/release.tar.gz", - "version": "6.2.2", + "hash": "sha256-/vYEBgrlTImksgNfJafTvIiBxAZ8obwou8YjDM2P+aw=", + "url": "https://github.com/zorn-v/nextcloud-social-login/releases/download/v6.2.3/release.tar.gz", + "version": "6.2.3", "description": "# Social Login\n\nMake it possible to create users and log in via Telegram, OAuth, or OpenID.\n\nFor OAuth, you must create an app with certain providers. Login buttons will appear on the login page if an app ID is specified. Settings are located in the \"Social login\" section of the settings page.\n\n## Installation\n\nLog in to your Nextcloud installation as an administrator. Under \"Apps\", click \"Download and enable\" next to the \"Social Login\" app.\n\nSee below for setup and configuration instructions.\n\n## Custom OAuth2/OIDC Groups\n\nYou can use groups from your custom provider. For this, specify the \"Groups claim\" in the custom OAuth2/OIDC provider settings. This claim should be returned from the provider in the `id_token` or at the user info endpoint. The format should be an `array` or a comma-separated string. E.g., (with a claim named `roles`):\n\n```json\n{\"roles\": [\"admin\", \"user\"]}\n```\nor\n```json\n{\"roles\": \"admin,user\"}\n```\n\nNested claims are also supported. For example, `resource_access.client-id.roles` for:\n\n```json\n\"resource_access\": {\n \"client-id\": {\n \"roles\": [\n \"client-role-1\",\n \"client-role-2\"\n ]\n }\n}\n```\n\n**DisplayName** support is also available:\n```json\n{\"roles\": [{\"gid\": 1, \"displayName\": \"admin\"}, {\"gid\": 2, \"displayName\": \"user\"}]}\n```\n\nYou can use provider groups in two ways:\n\n1. Map provider groups to existing Nextcloud groups.\n2. Create provider groups in Nextcloud and associate them with users (if the appropriate option is enabled).\n\nTo sync groups on every login, ensure the \"Update user profile every login\" setting is checked.\n\n## Examples for Groups\n\n* Configure WSO2IS to return a roles claim with OIDC [here](https://medium.com/@dewni.matheesha/claim-mapping-and-retrieving-end-user-information-in-wso2is-cffd5f3937ff).\n* [GitLab OIDC configuration to allow specific GitLab groups](https://github.com/zorn-v/nextcloud-social-login/blob/master/docs/sso/gitlab.md).\n\n## Built-in OAuth Providers\n\nCopy the link from a specific login button to get the correct \"redirect URL\" for OAuth app settings.\n\n* [Amazon](https://developer.amazon.com/loginwithamazon/console/site/lwa/overview.html)\n* [Apple](https://github.com/zorn-v/nextcloud-social-login/blob/master/docs/sso/apple.md)\n* [Codeberg](https://github.com/zorn-v/nextcloud-social-login/blob/master/docs/sso/codeberg.md)\n* [Discord](#configure-discord)\n* [Facebook](https://github.com/zorn-v/nextcloud-social-login/blob/master/docs/sso/facebook.md)\n* [GitHub](https://github.com/settings/developers)\n* [GitLab](https://github.com/zorn-v/nextcloud-social-login/blob/master/docs/sso/gitlab.md)\n* [Google](https://github.com/zorn-v/nextcloud-social-login/blob/master/docs/sso/google.md)\n* [Keycloak](https://github.com/zorn-v/nextcloud-social-login/blob/master/docs/sso/keycloak.md)\n* [Mail.ru](https://github.com/zorn-v/nextcloud-social-login/blob/master/docs/sso/mailru.md)\n* **PlexTv**: Use any title as the app ID.\n* [Telegram](https://github.com/zorn-v/nextcloud-social-login/blob/master/docs/sso/telegram.md)\n* [Twitter](https://github.com/zorn-v/nextcloud-social-login/blob/master/docs/sso/twitter.md)\n\nFor details about Google's \"Allow login only from specified domain\" setting, see [#44](https://github.com/zorn-v/nextcloud-social-login/issues/44). Use a comma-separated list for multiple domains.\n\n## Configuration\n\nAdd `'social_login_auto_redirect' => true` to `config.php` to automatically redirect unauthorized users to social login if only one provider is configured. To temporarily disable this (e.g., for local admin login), add `noredir=1` to the login URL: `https://cloud.domain.com/login?noredir=1`.\n\nConfigure HTTP client options using:\n```php\n 'social_login_http_client' => [\n 'timeout' => 45,\n 'proxy' => 'socks4://127.0.0.1:9050', // See for allowed formats\n ],\n```\nin `config.php`.\n\n### Configure a Provider via CLI\n\nUse the `occ` utility to configure providers via the command line. Replace variables and URLs with your deployment values:\n```bash\nphp occ config:app:set sociallogin custom_providers --value='{\"custom_oidc\": [{\"name\": \"gitlab_oidc\", \"title\": \"Gitlab\", \"authorizeUrl\": \"https://gitlab.my-domain.org/oauth/authorize\", \"tokenUrl\": \"https://gitlab.my-domain.org/oauth/token\", \"userInfoUrl\": \"https://gitlab.my-domain.org/oauth/userinfo\", \"logoutUrl\": \"\", \"clientId\": \"$my_application_id\", \"clientSecret\": \"$my_super_secret_secret\", \"scope\": \"openid\", \"groupsClaim\": \"groups\", \"style\": \"gitlab\", \"defaultGroup\": \"\"}]}'\n```\nFor Docker, prepend `docker exec -t -uwww-data CONTAINER_NAME` to the command or run interactively via `docker exec -it -uwww-data CONTAINER_NAME sh`.\n\nTo inspect configurations:\n```sql\nmysql -u nextcloud -p nextcloud\nPassword: \n\n> SELECT * FROM oc_appconfig WHERE appid='sociallogin';\n```\nOr run:\n```bash\ndocker exec -t -uwww-data CONTAINER_NAME php occ config:app:get sociallogin custom_providers\n```\n\n### Configure Discord\n\n1. Create a Discord application at [Discord Developer Portal](https://discord.com/developers/applications).\n2. Navigate to `Settings > OAuth2 > General`. Add a redirect URL: `https://nextcloud.mydomain.com/apps/sociallogin/oauth/discord`.\n3. Copy the `CLIENT ID` and generate a `CLIENT SECRET`.\n4. In Nextcloud, go to `Settings > Social Login`. Paste the `CLIENT ID` into \"App id\" and `CLIENT SECRET` into \"Secret\".\n5. Select a default group for new users.\n6. For group mapping, see [#395](https://github.com/zorn-v/nextcloud-social-login/pull/395).\n\n## Hint\n\n### Callback (Reply) URL\nCopy the link from a login button on the Nextcloud login page and use it as the callback URL on your provider's site. To make the button visible temporarily, fill provider settings with placeholder data and update later.\n\nIf you encounter callback URL errors despite correct settings, ensure your Nextcloud server generates HTTPS URLs by adding `'overwriteprotocol' => 'https'` to `config.php`.", "homepage": "https://github.com/zorn-v/nextcloud-social-login", "licenses": [ @@ -480,9 +480,9 @@ ] }, "whiteboard": { - "hash": "sha256-2CSc9gRXAHaKiq4KfVl+44eWhtBFgjHYbMeTwE18xuA=", - "url": "https://github.com/nextcloud-releases/whiteboard/releases/download/v1.3.0/whiteboard-v1.3.0.tar.gz", - "version": "1.3.0", + "hash": "sha256-i8qk1RZrLbF0Mex4lgVZp092ZrsUvosYeiLcJ4WMosQ=", + "url": "https://github.com/nextcloud-releases/whiteboard/releases/download/v1.4.0/whiteboard-v1.4.0.tar.gz", + "version": "1.4.0", "description": "The official whiteboard app for Nextcloud. It allows users to create and share whiteboards with other users and collaborate in real-time.\n\n**Whiteboard requires a separate collaboration server to work.** Please see the [documentation](https://github.com/nextcloud/whiteboard?tab=readme-ov-file#backend) on how to install it.\n\n- ๐ŸŽจ Drawing shapes, writing text, connecting elements\n- ๐Ÿ“ Real-time collaboration\n- ๐Ÿ–ผ๏ธ Add images with drag and drop\n- ๐Ÿ“Š Easily add mermaid diagrams\n- โœจ Use the Smart Picker to embed other elements from Nextcloud\n- ๐Ÿ“ฆ Image export\n- ๐Ÿ’ช Strong foundation: We use Excalidraw as our base library", "homepage": "https://github.com/nextcloud/whiteboard", "licenses": [ diff --git a/pkgs/servers/nextcloud/packages/32.json b/pkgs/servers/nextcloud/packages/32.json index 4efd07211f29..f0eaf8531e14 100644 --- a/pkgs/servers/nextcloud/packages/32.json +++ b/pkgs/servers/nextcloud/packages/32.json @@ -20,9 +20,9 @@ ] }, "collectives": { - "hash": "sha256-vWPT3FBSZlgA1z1zH1o1Kpd9JOmt2Ykfh3JMtMLWTjI=", - "url": "https://github.com/nextcloud/collectives/releases/download/v3.2.1/collectives-3.2.1.tar.gz", - "version": "3.2.1", + "hash": "sha256-ezFo8Vv8qFNzW9ZevcOmZdKBtmpDY6SpRqX4R/2UT1E=", + "url": "https://github.com/nextcloud/collectives/releases/download/v3.2.4/collectives-3.2.4.tar.gz", + "version": "3.2.4", "description": "Collectives is a Nextcloud App for activist and community projects to organize together.\nCome and gather in collectives to build shared knowledge.\n\n* ๐Ÿ‘ฅ **Collective and non-hierarchical workflow by heart**: Collectives are\n tied to a [Nextcloud Team](https://github.com/nextcloud/circles) and\n owned by the collective.\n* ๐Ÿ“ **Collaborative page editing** like known from Etherpad thanks to the\n [Text app](https://github.com/nextcloud/text).\n* ๐Ÿ”ค **Well-known [Markdown](https://en.wikipedia.org/wiki/Markdown) syntax**\n for page formatting.\n\n## Installation\n\nIn your Nextcloud instance, simply navigate to **ยปAppsยซ**, find the\n**ยปTeamsยซ** and **ยปCollectivesยซ** apps and enable them.", "homepage": "https://github.com/nextcloud/collectives", "licenses": [ @@ -30,9 +30,9 @@ ] }, "contacts": { - "hash": "sha256-GTIsL5oY6Kb8Ga79VL7WGD51lmxUvE2cHN38anvyf6w=", - "url": "https://github.com/nextcloud-releases/contacts/releases/download/v8.0.4/contacts-v8.0.4.tar.gz", - "version": "8.0.4", + "hash": "sha256-DKCZD5wMZu2yWy6Wjv2/L8ZQG1nBgtXJmUEsAVICFjo=", + "url": "https://github.com/nextcloud-releases/contacts/releases/download/v8.0.5/contacts-v8.0.5.tar.gz", + "version": "8.0.5", "description": "The Nextcloud contacts app is a user interface for Nextcloud's CardDAV server. Easily sync contacts from various devices with your Nextcloud and edit them online.\n\n* ๐Ÿš€ **Integration with other Nextcloud apps!** Currently Mail and Calendar โ€“ more to come.\n* ๐ŸŽ‰ **Never forget a birthday!** You can sync birthdays and other recurring events with your Nextcloud Calendar.\n* ๐Ÿ‘ฅ **Sharing of Adressbooks!** You want to share your contacts with your friends or coworkers? No problem!\n* ๐Ÿ™ˆ **Weโ€™re not reinventing the wheel!** Based on the great and open SabreDAV library.", "homepage": "https://github.com/nextcloud/contacts#readme", "licenses": [ @@ -40,9 +40,9 @@ ] }, "cookbook": { - "hash": "sha256-pdmltxubvC2+h5U5edTB8X5M8WW+wBShIEpkbR0yaQ0=", - "url": "https://github.com/christianlupus-nextcloud/cookbook-releases/releases/download/v0.11.4/cookbook-0.11.4.tar.gz", - "version": "0.11.4", + "hash": "sha256-Bw5Oga5zawiicIR9tOLSflK0258Uy7q/9zJsXS5Ggd4=", + "url": "https://github.com/christianlupus-nextcloud/cookbook-releases/releases/download/v0.11.5/cookbook-0.11.5.tar.gz", + "version": "0.11.5", "description": "A library for all your recipes. It uses JSON files following the schema.org recipe format. To add a recipe to the collection, you can paste in the URL of the recipe, and the provided web page will be parsed and downloaded to whichever folder you specify in the app settings.", "homepage": "https://github.com/nextcloud/cookbook/", "licenses": [ @@ -120,9 +120,9 @@ ] }, "gpoddersync": { - "hash": "sha256-xMSo5D3w/qIMxLclSTmBPVBHwNkyTbluqlXWtdbLUYk=", - "url": "https://github.com/thrillfall/nextcloud-gpodder/releases/download/3.13.2/gpoddersync.tar.gz", - "version": "3.13.1", + "hash": "sha256-EQVs1fe0ierjqFZ5+KVc1Yj67zrwjLBAzY5A+QsC7AU=", + "url": "https://github.com/thrillfall/nextcloud-gpodder/releases/download/3.13.2r/gpoddersync.tar.gz", + "version": "3.13.2", "description": "Expose GPodder API to sync podcast consumer apps like AntennaPod", "homepage": "https://github.com/thrillfall/nextcloud-gpodder", "licenses": [ @@ -200,9 +200,9 @@ ] }, "news": { - "hash": "sha256-K93swGriEwm1zBq9H7F4P2fHmTanYddFARfQp456bds=", - "url": "https://github.com/nextcloud/news/releases/download/27.0.1/news.tar.gz", - "version": "27.0.1", + "hash": "sha256-bKIEeRVmDoDjab8dusdG+q7Ms/gaOUFUyCH1C1pKJ04=", + "url": "https://github.com/nextcloud/news/releases/download/27.1.0/news.tar.gz", + "version": "27.1.0", "description": "๐Ÿ“ฐ A RSS/Atom Feed reader App for Nextcloud\n\n- ๐Ÿ“ฒ Synchronize your feeds with multiple mobile or desktop [clients](https://nextcloud.github.io/news/clients/)\n- ๐Ÿ”„ Automatic updates of your news feeds\n- ๐Ÿ†“ Free and open source under AGPLv3, no ads or premium functions\n\n**System Cron is currently required for this app to work**\n\nRequirements can be found [here](https://nextcloud.github.io/news/install/#dependencies)\n\nThe Changelog is available [here](https://github.com/nextcloud/news/blob/master/CHANGELOG.md)\n\nCreate a [bug report](https://github.com/nextcloud/news/issues/new/choose)\n\nCreate a [feature request](https://github.com/nextcloud/news/discussions/new)\n\nReport a [feed issue](https://github.com/nextcloud/news/discussions/new)", "homepage": "https://github.com/nextcloud/news", "licenses": [ @@ -320,9 +320,9 @@ ] }, "sociallogin": { - "hash": "sha256-zuzQKtU+sEEYhBZ4UMfY1eMSsDfe7o/ymWYv2SJBiHw=", - "url": "https://github.com/zorn-v/nextcloud-social-login/releases/download/v6.2.2/release.tar.gz", - "version": "6.2.2", + "hash": "sha256-/vYEBgrlTImksgNfJafTvIiBxAZ8obwou8YjDM2P+aw=", + "url": "https://github.com/zorn-v/nextcloud-social-login/releases/download/v6.2.3/release.tar.gz", + "version": "6.2.3", "description": "# Social Login\n\nMake it possible to create users and log in via Telegram, OAuth, or OpenID.\n\nFor OAuth, you must create an app with certain providers. Login buttons will appear on the login page if an app ID is specified. Settings are located in the \"Social login\" section of the settings page.\n\n## Installation\n\nLog in to your Nextcloud installation as an administrator. Under \"Apps\", click \"Download and enable\" next to the \"Social Login\" app.\n\nSee below for setup and configuration instructions.\n\n## Custom OAuth2/OIDC Groups\n\nYou can use groups from your custom provider. For this, specify the \"Groups claim\" in the custom OAuth2/OIDC provider settings. This claim should be returned from the provider in the `id_token` or at the user info endpoint. The format should be an `array` or a comma-separated string. E.g., (with a claim named `roles`):\n\n```json\n{\"roles\": [\"admin\", \"user\"]}\n```\nor\n```json\n{\"roles\": \"admin,user\"}\n```\n\nNested claims are also supported. For example, `resource_access.client-id.roles` for:\n\n```json\n\"resource_access\": {\n \"client-id\": {\n \"roles\": [\n \"client-role-1\",\n \"client-role-2\"\n ]\n }\n}\n```\n\n**DisplayName** support is also available:\n```json\n{\"roles\": [{\"gid\": 1, \"displayName\": \"admin\"}, {\"gid\": 2, \"displayName\": \"user\"}]}\n```\n\nYou can use provider groups in two ways:\n\n1. Map provider groups to existing Nextcloud groups.\n2. Create provider groups in Nextcloud and associate them with users (if the appropriate option is enabled).\n\nTo sync groups on every login, ensure the \"Update user profile every login\" setting is checked.\n\n## Examples for Groups\n\n* Configure WSO2IS to return a roles claim with OIDC [here](https://medium.com/@dewni.matheesha/claim-mapping-and-retrieving-end-user-information-in-wso2is-cffd5f3937ff).\n* [GitLab OIDC configuration to allow specific GitLab groups](https://github.com/zorn-v/nextcloud-social-login/blob/master/docs/sso/gitlab.md).\n\n## Built-in OAuth Providers\n\nCopy the link from a specific login button to get the correct \"redirect URL\" for OAuth app settings.\n\n* [Amazon](https://developer.amazon.com/loginwithamazon/console/site/lwa/overview.html)\n* [Apple](https://github.com/zorn-v/nextcloud-social-login/blob/master/docs/sso/apple.md)\n* [Codeberg](https://github.com/zorn-v/nextcloud-social-login/blob/master/docs/sso/codeberg.md)\n* [Discord](#configure-discord)\n* [Facebook](https://github.com/zorn-v/nextcloud-social-login/blob/master/docs/sso/facebook.md)\n* [GitHub](https://github.com/settings/developers)\n* [GitLab](https://github.com/zorn-v/nextcloud-social-login/blob/master/docs/sso/gitlab.md)\n* [Google](https://github.com/zorn-v/nextcloud-social-login/blob/master/docs/sso/google.md)\n* [Keycloak](https://github.com/zorn-v/nextcloud-social-login/blob/master/docs/sso/keycloak.md)\n* [Mail.ru](https://github.com/zorn-v/nextcloud-social-login/blob/master/docs/sso/mailru.md)\n* **PlexTv**: Use any title as the app ID.\n* [Telegram](https://github.com/zorn-v/nextcloud-social-login/blob/master/docs/sso/telegram.md)\n* [Twitter](https://github.com/zorn-v/nextcloud-social-login/blob/master/docs/sso/twitter.md)\n\nFor details about Google's \"Allow login only from specified domain\" setting, see [#44](https://github.com/zorn-v/nextcloud-social-login/issues/44). Use a comma-separated list for multiple domains.\n\n## Configuration\n\nAdd `'social_login_auto_redirect' => true` to `config.php` to automatically redirect unauthorized users to social login if only one provider is configured. To temporarily disable this (e.g., for local admin login), add `noredir=1` to the login URL: `https://cloud.domain.com/login?noredir=1`.\n\nConfigure HTTP client options using:\n```php\n 'social_login_http_client' => [\n 'timeout' => 45,\n 'proxy' => 'socks4://127.0.0.1:9050', // See for allowed formats\n ],\n```\nin `config.php`.\n\n### Configure a Provider via CLI\n\nUse the `occ` utility to configure providers via the command line. Replace variables and URLs with your deployment values:\n```bash\nphp occ config:app:set sociallogin custom_providers --value='{\"custom_oidc\": [{\"name\": \"gitlab_oidc\", \"title\": \"Gitlab\", \"authorizeUrl\": \"https://gitlab.my-domain.org/oauth/authorize\", \"tokenUrl\": \"https://gitlab.my-domain.org/oauth/token\", \"userInfoUrl\": \"https://gitlab.my-domain.org/oauth/userinfo\", \"logoutUrl\": \"\", \"clientId\": \"$my_application_id\", \"clientSecret\": \"$my_super_secret_secret\", \"scope\": \"openid\", \"groupsClaim\": \"groups\", \"style\": \"gitlab\", \"defaultGroup\": \"\"}]}'\n```\nFor Docker, prepend `docker exec -t -uwww-data CONTAINER_NAME` to the command or run interactively via `docker exec -it -uwww-data CONTAINER_NAME sh`.\n\nTo inspect configurations:\n```sql\nmysql -u nextcloud -p nextcloud\nPassword: \n\n> SELECT * FROM oc_appconfig WHERE appid='sociallogin';\n```\nOr run:\n```bash\ndocker exec -t -uwww-data CONTAINER_NAME php occ config:app:get sociallogin custom_providers\n```\n\n### Configure Discord\n\n1. Create a Discord application at [Discord Developer Portal](https://discord.com/developers/applications).\n2. Navigate to `Settings > OAuth2 > General`. Add a redirect URL: `https://nextcloud.mydomain.com/apps/sociallogin/oauth/discord`.\n3. Copy the `CLIENT ID` and generate a `CLIENT SECRET`.\n4. In Nextcloud, go to `Settings > Social Login`. Paste the `CLIENT ID` into \"App id\" and `CLIENT SECRET` into \"Secret\".\n5. Select a default group for new users.\n6. For group mapping, see [#395](https://github.com/zorn-v/nextcloud-social-login/pull/395).\n\n## Hint\n\n### Callback (Reply) URL\nCopy the link from a login button on the Nextcloud login page and use it as the callback URL on your provider's site. To make the button visible temporarily, fill provider settings with placeholder data and update later.\n\nIf you encounter callback URL errors despite correct settings, ensure your Nextcloud server generates HTTPS URLs by adding `'overwriteprotocol' => 'https'` to `config.php`.", "homepage": "https://github.com/zorn-v/nextcloud-social-login", "licenses": [ @@ -330,9 +330,9 @@ ] }, "spreed": { - "hash": "sha256-tWWFUrJ5XQdXYb8BfoxHCFrMCKj+cwLit1zkoJtWfwk=", - "url": "https://github.com/nextcloud-releases/spreed/releases/download/v22.0.0/spreed-v22.0.0.tar.gz", - "version": "22.0.0", + "hash": "sha256-w1rNmKWWhPbwhcc6F8WX5ouW8zsrl6vqpHQZGlHdSJM=", + "url": "https://github.com/nextcloud-releases/spreed/releases/download/v22.0.2/spreed-v22.0.2.tar.gz", + "version": "22.0.2", "description": "Chat, video & audio-conferencing using WebRTC\n\n* ๐Ÿ’ฌ **Chat** Nextcloud Talk comes with a simple text chat, allowing you to share or upload files from your Nextcloud Files app or local device and mention other participants.\n* ๐Ÿ‘ฅ **Private, group, public and password protected calls!** Invite someone, a whole group or send a public link to invite to a call.\n* ๐ŸŒ **Federated chats** Chat with other Nextcloud users on their servers\n* ๐Ÿ’ป **Screen sharing!** Share your screen with the participants of your call.\n* ๐Ÿš€ **Integration with other Nextcloud apps** like Files, Calendar, User status, Dashboard, Flow, Maps, Smart picker, Contacts, Deck, and many more.\n* ๐ŸŒ‰ **Sync with other chat solutions** With [Matterbridge](https://github.com/42wim/matterbridge/) being integrated in Talk, you can easily sync a lot of other chat solutions to Nextcloud Talk and vice-versa.", "homepage": "https://github.com/nextcloud/spreed", "licenses": [ @@ -430,9 +430,9 @@ ] }, "whiteboard": { - "hash": "sha256-2CSc9gRXAHaKiq4KfVl+44eWhtBFgjHYbMeTwE18xuA=", - "url": "https://github.com/nextcloud-releases/whiteboard/releases/download/v1.3.0/whiteboard-v1.3.0.tar.gz", - "version": "1.3.0", + "hash": "sha256-i8qk1RZrLbF0Mex4lgVZp092ZrsUvosYeiLcJ4WMosQ=", + "url": "https://github.com/nextcloud-releases/whiteboard/releases/download/v1.4.0/whiteboard-v1.4.0.tar.gz", + "version": "1.4.0", "description": "The official whiteboard app for Nextcloud. It allows users to create and share whiteboards with other users and collaborate in real-time.\n\n**Whiteboard requires a separate collaboration server to work.** Please see the [documentation](https://github.com/nextcloud/whiteboard?tab=readme-ov-file#backend) on how to install it.\n\n- ๐ŸŽจ Drawing shapes, writing text, connecting elements\n- ๐Ÿ“ Real-time collaboration\n- ๐Ÿ–ผ๏ธ Add images with drag and drop\n- ๐Ÿ“Š Easily add mermaid diagrams\n- โœจ Use the Smart Picker to embed other elements from Nextcloud\n- ๐Ÿ“ฆ Image export\n- ๐Ÿ’ช Strong foundation: We use Excalidraw as our base library", "homepage": "https://github.com/nextcloud/whiteboard", "licenses": [ diff --git a/pkgs/servers/sql/postgresql/ext/pg_repack.nix b/pkgs/servers/sql/postgresql/ext/pg_repack.nix index 8131f5d49ed8..d56ef90deba4 100644 --- a/pkgs/servers/sql/postgresql/ext/pg_repack.nix +++ b/pkgs/servers/sql/postgresql/ext/pg_repack.nix @@ -10,7 +10,7 @@ postgresqlBuildExtension (finalAttrs: { pname = "pg_repack"; - version = "1.5.2"; + version = "1.5.3"; buildInputs = postgresql.buildInputs; @@ -18,7 +18,7 @@ postgresqlBuildExtension (finalAttrs: { owner = "reorg"; repo = "pg_repack"; tag = "ver_${finalAttrs.version}"; - hash = "sha256-wfjiLkx+S3zVrAynisX1GdazueVJ3EOwQEPcgUQt7eA="; + hash = "sha256-Ufh/dKrKumRKeQ/CpwvxbjAmgILAn04BduPZMRvS+nU="; }; passthru.updateScript = gitUpdater {