mirror of
https://github.com/TecharoHQ/anubis.git
synced 2026-04-11 19:18:46 +00:00
Compare commits
19 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
c28b191b79 | ||
|
|
6e964e6449 | ||
|
|
6a12efee08 | ||
|
|
5e1abdd31c | ||
|
|
cb3bbbd4c8 | ||
|
|
d51b7ec0aa | ||
|
|
b164048dcf | ||
|
|
6c0ff3f4d5 | ||
|
|
9009596ded | ||
|
|
f4298b993f | ||
|
|
659b577e0e | ||
|
|
2b103a9ec7 | ||
|
|
a0805cad16 | ||
|
|
22ada6251f | ||
|
|
092b80ba55 | ||
|
|
3bd2e4a584 | ||
|
|
39dc3c0317 | ||
|
|
624b935ecc | ||
|
|
529f65674e |
17
.github/actions/spelling/README.md
vendored
Normal file
17
.github/actions/spelling/README.md
vendored
Normal file
@@ -0,0 +1,17 @@
|
|||||||
|
# check-spelling/check-spelling configuration
|
||||||
|
|
||||||
|
File | Purpose | Format | Info
|
||||||
|
-|-|-|-
|
||||||
|
[dictionary.txt](dictionary.txt) | Replacement dictionary (creating this file will override the default dictionary) | one word per line | [dictionary](https://github.com/check-spelling/check-spelling/wiki/Configuration#dictionary)
|
||||||
|
[allow.txt](allow.txt) | Add words to the dictionary | one word per line (only letters and `'`s allowed) | [allow](https://github.com/check-spelling/check-spelling/wiki/Configuration#allow)
|
||||||
|
[reject.txt](reject.txt) | Remove words from the dictionary (after allow) | grep pattern matching whole dictionary words | [reject](https://github.com/check-spelling/check-spelling/wiki/Configuration-Examples%3A-reject)
|
||||||
|
[excludes.txt](excludes.txt) | Files to ignore entirely | perl regular expression | [excludes](https://github.com/check-spelling/check-spelling/wiki/Configuration-Examples%3A-excludes)
|
||||||
|
[only.txt](only.txt) | Only check matching files (applied after excludes) | perl regular expression | [only](https://github.com/check-spelling/check-spelling/wiki/Configuration-Examples%3A-only)
|
||||||
|
[patterns.txt](patterns.txt) | Patterns to ignore from checked lines | perl regular expression (order matters, first match wins) | [patterns](https://github.com/check-spelling/check-spelling/wiki/Configuration-Examples%3A-patterns)
|
||||||
|
[candidate.patterns](candidate.patterns) | Patterns that might be worth adding to [patterns.txt](patterns.txt) | perl regular expression with optional comment block introductions (all matches will be suggested) | [candidates](https://github.com/check-spelling/check-spelling/wiki/Feature:-Suggest-patterns)
|
||||||
|
[line_forbidden.patterns](line_forbidden.patterns) | Patterns to flag in checked lines | perl regular expression (order matters, first match wins) | [patterns](https://github.com/check-spelling/check-spelling/wiki/Configuration-Examples%3A-patterns)
|
||||||
|
[expect.txt](expect.txt) | Expected words that aren't in the dictionary | one word per line (sorted, alphabetically) | [expect](https://github.com/check-spelling/check-spelling/wiki/Configuration#expect)
|
||||||
|
[advice.md](advice.md) | Supplement for GitHub comment when unrecognized words are found | GitHub Markdown | [advice](https://github.com/check-spelling/check-spelling/wiki/Configuration-Examples%3A-advice)
|
||||||
|
|
||||||
|
Note: you can replace any of these files with a directory by the same name (minus the suffix)
|
||||||
|
and then include multiple files inside that directory (with that suffix) to merge multiple files together.
|
||||||
31
.github/actions/spelling/advice.md
vendored
Normal file
31
.github/actions/spelling/advice.md
vendored
Normal file
@@ -0,0 +1,31 @@
|
|||||||
|
<!-- See https://github.com/check-spelling/check-spelling/wiki/Configuration-Examples%3A-advice --> <!-- markdownlint-disable MD033 MD041 -->
|
||||||
|
<details><summary>If the flagged items are :exploding_head: false positives</summary>
|
||||||
|
|
||||||
|
If items relate to a ...
|
||||||
|
* binary file (or some other file you wouldn't want to check at all).
|
||||||
|
|
||||||
|
Please add a file path to the `excludes.txt` file matching the containing file.
|
||||||
|
|
||||||
|
File paths are Perl 5 Regular Expressions - you can [test](
|
||||||
|
https://www.regexplanet.com/advanced/perl/) yours before committing to verify it will match your files.
|
||||||
|
|
||||||
|
`^` refers to the file's path from the root of the repository, so `^README\.md$` would exclude [README.md](
|
||||||
|
../tree/HEAD/README.md) (on whichever branch you're using).
|
||||||
|
|
||||||
|
* well-formed pattern.
|
||||||
|
|
||||||
|
If you can write a [pattern](
|
||||||
|
https://github.com/check-spelling/check-spelling/wiki/Configuration-Examples:-patterns
|
||||||
|
) that would match it,
|
||||||
|
try adding it to the `patterns.txt` file.
|
||||||
|
|
||||||
|
Patterns are Perl 5 Regular Expressions - you can [test](
|
||||||
|
https://www.regexplanet.com/advanced/perl/) yours before committing to verify it will match your lines.
|
||||||
|
|
||||||
|
Note that patterns can't match multiline strings.
|
||||||
|
|
||||||
|
</details>
|
||||||
|
|
||||||
|
<!-- adoption information-->
|
||||||
|
:steam_locomotive: If you're seeing this message and your PR is from a branch that doesn't have check-spelling,
|
||||||
|
please merge to your PR's base branch to get the version configured for your repository.
|
||||||
5
.github/actions/spelling/allow.txt
vendored
Normal file
5
.github/actions/spelling/allow.txt
vendored
Normal file
@@ -0,0 +1,5 @@
|
|||||||
|
github
|
||||||
|
https
|
||||||
|
ssh
|
||||||
|
ubuntu
|
||||||
|
workarounds
|
||||||
779
.github/actions/spelling/candidate.patterns
vendored
Normal file
779
.github/actions/spelling/candidate.patterns
vendored
Normal file
@@ -0,0 +1,779 @@
|
|||||||
|
# Repeated letters
|
||||||
|
#\b([a-z])\g{-1}{2,}\b
|
||||||
|
|
||||||
|
# marker to ignore all code on line
|
||||||
|
^.*/\* #no-spell-check-line \*/.*$
|
||||||
|
# marker to ignore all code on line
|
||||||
|
^.*\bno-spell-check(?:-line|)(?:\s.*|)$
|
||||||
|
|
||||||
|
# https://cspell.org/configuration/document-settings/
|
||||||
|
# cspell inline
|
||||||
|
^.*\b[Cc][Ss][Pp][Ee][Ll]{2}:\s*[Dd][Ii][Ss][Aa][Bb][Ll][Ee]-[Ll][Ii][Nn][Ee]\b
|
||||||
|
|
||||||
|
# copyright
|
||||||
|
Copyright (?:\([Cc]\)|)(?:[-\d, ]|and)+(?: [A-Z][a-z]+ [A-Z][a-z]+,?)+
|
||||||
|
|
||||||
|
# patch hunk comments
|
||||||
|
^@@ -\d+(?:,\d+|) \+\d+(?:,\d+|) @@ .*
|
||||||
|
# git index header
|
||||||
|
index (?:[0-9a-z]{7,40},|)[0-9a-z]{7,40}\.\.[0-9a-z]{7,40}
|
||||||
|
|
||||||
|
# file permissions
|
||||||
|
['"`\s][-bcdLlpsw](?:[-r][-w][-Ssx]){2}[-r][-w][-SsTtx]\+?['"`\s]
|
||||||
|
|
||||||
|
# css fonts
|
||||||
|
\bfont(?:-family|):[^;}]+
|
||||||
|
|
||||||
|
# css url wrappings
|
||||||
|
\burl\([^)]+\)
|
||||||
|
|
||||||
|
# cid urls
|
||||||
|
(['"])cid:.*?\g{-1}
|
||||||
|
|
||||||
|
# data url in parens
|
||||||
|
\(data:(?:[^) ][^)]*?|)(?:[A-Z]{3,}|[A-Z][a-z]{2,}|[a-z]{3,})[^)]*\)
|
||||||
|
# data url in quotes
|
||||||
|
([`'"])data:(?:[^ `'"].*?|)(?:[A-Z]{3,}|[A-Z][a-z]{2,}|[a-z]{3,}).*\g{-1}
|
||||||
|
# data url
|
||||||
|
\bdata:[-a-zA-Z=;:/0-9+]*,\S*
|
||||||
|
|
||||||
|
# https/http/file urls
|
||||||
|
(?:\b(?:https?|ftp|file)://)[-A-Za-z0-9+&@#/*%?=~_|!:,.;]+[-A-Za-z0-9+&@#/*%=~_|]
|
||||||
|
|
||||||
|
# mailto urls
|
||||||
|
mailto:[-a-zA-Z=;:/?%&0-9+@._]{3,}
|
||||||
|
|
||||||
|
# magnet urls
|
||||||
|
magnet:[?=:\w]+
|
||||||
|
|
||||||
|
# magnet urls
|
||||||
|
"magnet:[^"]+"
|
||||||
|
|
||||||
|
# obs:
|
||||||
|
"obs:[^"]*"
|
||||||
|
|
||||||
|
# The `\b` here means a break, it's the fancy way to handle urls, but it makes things harder to read
|
||||||
|
# In this examples content, I'm using a number of different ways to match things to show various approaches
|
||||||
|
# asciinema
|
||||||
|
\basciinema\.org/a/[0-9a-zA-Z]+
|
||||||
|
|
||||||
|
# asciinema v2
|
||||||
|
^\[\d+\.\d+, "[io]", ".*"\]$
|
||||||
|
|
||||||
|
# apple
|
||||||
|
\bdeveloper\.apple\.com/[-\w?=/]+
|
||||||
|
# Apple music
|
||||||
|
\bembed\.music\.apple\.com/fr/playlist/usr-share/[-\w.]+
|
||||||
|
|
||||||
|
# appveyor api
|
||||||
|
\bci\.appveyor\.com/api/projects/status/[0-9a-z]+
|
||||||
|
# appveyor project
|
||||||
|
\bci\.appveyor\.com/project/(?:[^/\s"]*/){2}builds?/\d+/job/[0-9a-z]+
|
||||||
|
|
||||||
|
# Amazon
|
||||||
|
|
||||||
|
# Amazon
|
||||||
|
\bamazon\.com/[-\w]+/(?:dp/[0-9A-Z]+|)
|
||||||
|
# AWS ARN
|
||||||
|
arn:aws:[-/:\w]+
|
||||||
|
# AWS S3
|
||||||
|
\b\w*\.s3[^.]*\.amazonaws\.com/[-\w/&#%_?:=]*
|
||||||
|
# AWS execute-api
|
||||||
|
\b[0-9a-z]{10}\.execute-api\.[-0-9a-z]+\.amazonaws\.com\b
|
||||||
|
# AWS ELB
|
||||||
|
\b\w+\.[-0-9a-z]+\.elb\.amazonaws\.com\b
|
||||||
|
# AWS SNS
|
||||||
|
\bsns\.[-0-9a-z]+.amazonaws\.com/[-\w/&#%_?:=]*
|
||||||
|
# AWS VPC
|
||||||
|
vpc-\w+
|
||||||
|
|
||||||
|
# While you could try to match `http://` and `https://` by using `s?` in `https?://`, sometimes there
|
||||||
|
# YouTube url
|
||||||
|
\b(?:(?:www\.|)youtube\.com|youtu.be)/(?:channel/|embed/|user/|playlist\?list=|watch\?v=|v/|)[-a-zA-Z0-9?&=_%]*
|
||||||
|
# YouTube music
|
||||||
|
\bmusic\.youtube\.com/youtubei/v1/browse(?:[?&]\w+=[-a-zA-Z0-9?&=_]*)
|
||||||
|
# YouTube tag
|
||||||
|
<\s*youtube\s+id=['"][-a-zA-Z0-9?_]*['"]
|
||||||
|
# YouTube image
|
||||||
|
\bimg\.youtube\.com/vi/[-a-zA-Z0-9?&=_]*
|
||||||
|
# Google Accounts
|
||||||
|
\baccounts.google.com/[-_/?=.:;+%&0-9a-zA-Z]*
|
||||||
|
# Google Analytics
|
||||||
|
\bgoogle-analytics\.com/collect.[-0-9a-zA-Z?%=&_.~]*
|
||||||
|
# Google APIs
|
||||||
|
\bgoogleapis\.(?:com|dev)/[a-z]+/(?:v\d+/|)[a-z]+/[-@:./?=\w+|&]+
|
||||||
|
# Google Artifact Registry
|
||||||
|
\.pkg\.dev(?:/[-\w]+)+(?::[-\w]+|)
|
||||||
|
# Google Storage
|
||||||
|
\b[-a-zA-Z0-9.]*\bstorage\d*\.googleapis\.com(?:/\S*|)
|
||||||
|
# Google Calendar
|
||||||
|
\bcalendar\.google\.com/calendar(?:/u/\d+|)/embed\?src=[@./?=\w&%]+
|
||||||
|
\w+\@group\.calendar\.google\.com\b
|
||||||
|
# Google DataStudio
|
||||||
|
\bdatastudio\.google\.com/(?:(?:c/|)u/\d+/|)(?:embed/|)(?:open|reporting|datasources|s)/[-0-9a-zA-Z]+(?:/page/[-0-9a-zA-Z]+|)
|
||||||
|
# The leading `/` here is as opposed to the `\b` above
|
||||||
|
# ... a short way to match `https://` or `http://` since most urls have one of those prefixes
|
||||||
|
# Google Docs
|
||||||
|
/docs\.google\.com/[a-z]+/(?:ccc\?key=\w+|(?:u/\d+|d/(?:e/|)[0-9a-zA-Z_-]+/)?(?:edit\?[-\w=#.]*|/\?[\w=&]*|))
|
||||||
|
# Google Drive
|
||||||
|
\bdrive\.google\.com/(?:file/d/|open)[-0-9a-zA-Z_?=]*
|
||||||
|
# Google Groups
|
||||||
|
\bgroups\.google\.com(?:/[a-z]+/(?:#!|)[^/\s"]+)*
|
||||||
|
# Google Maps
|
||||||
|
\bmaps\.google\.com/maps\?[\w&;=]*
|
||||||
|
# Google themes
|
||||||
|
themes\.googleusercontent\.com/static/fonts/[^/\s"]+/v\d+/[^.]+.
|
||||||
|
# Google CDN
|
||||||
|
\bclients2\.google(?:usercontent|)\.com[-0-9a-zA-Z/.]*
|
||||||
|
# Goo.gl
|
||||||
|
/goo\.gl/[a-zA-Z0-9]+
|
||||||
|
# Google Chrome Store
|
||||||
|
\bchrome\.google\.com/webstore/detail/[-\w]*(?:/\w*|)
|
||||||
|
# Google Books
|
||||||
|
\bgoogle\.(?:\w{2,4})/books(?:/\w+)*\?[-\w\d=&#.]*
|
||||||
|
# Google Fonts
|
||||||
|
\bfonts\.(?:googleapis|gstatic)\.com/[-/?=:;+&0-9a-zA-Z]*
|
||||||
|
# Google Forms
|
||||||
|
\bforms\.gle/\w+
|
||||||
|
# Google Scholar
|
||||||
|
\bscholar\.google\.com/citations\?user=[A-Za-z0-9_]+
|
||||||
|
# Google Colab Research Drive
|
||||||
|
\bcolab\.research\.google\.com/drive/[-0-9a-zA-Z_?=]*
|
||||||
|
# Google Cloud regions
|
||||||
|
(?:us|(?:north|south)america|europe|asia|australia|me|africa)-(?:north|south|east|west|central){1,2}\d+
|
||||||
|
|
||||||
|
# GitHub SHAs (api)
|
||||||
|
\bapi.github\.com/repos(?:/[^/\s"]+){3}/[0-9a-f]+\b
|
||||||
|
# GitHub SHAs (markdown)
|
||||||
|
(?:\[`?[0-9a-f]+`?\]\(https:/|)/(?:www\.|)github\.com(?:/[^/\s"]+){2,}(?:/[^/\s")]+)(?:[0-9a-f]+(?:[-0-9a-zA-Z/#.]*|)\b|)
|
||||||
|
# GitHub SHAs
|
||||||
|
\bgithub\.com(?:/[^/\s"]+){2}[@#][0-9a-f]+\b
|
||||||
|
# GitHub SHA refs
|
||||||
|
\[([0-9a-f]+)\]\(https://(?:www\.|)github.com/[-\w]+/[-\w]+/commit/\g{-1}[0-9a-f]*
|
||||||
|
# GitHub wiki
|
||||||
|
\bgithub\.com/(?:[^/]+/){2}wiki/(?:(?:[^/]+/|)_history|[^/]+(?:/_compare|)/[0-9a-f.]{40,})\b
|
||||||
|
# githubusercontent
|
||||||
|
/[-a-z0-9]+\.githubusercontent\.com/[-a-zA-Z0-9?&=_\/.]*
|
||||||
|
# githubassets
|
||||||
|
\bgithubassets.com/[0-9a-f]+(?:[-/\w.]+)
|
||||||
|
# gist github
|
||||||
|
\bgist\.github\.com/[^/\s"]+/[0-9a-f]+
|
||||||
|
# git.io
|
||||||
|
\bgit\.io/[0-9a-zA-Z]+
|
||||||
|
# GitHub JSON
|
||||||
|
"node_id": "[-a-zA-Z=;:/0-9+_]*"
|
||||||
|
# Contributor
|
||||||
|
\[[^\]]+\]\(https://github\.com/[^/\s"]+/?\)
|
||||||
|
# GHSA
|
||||||
|
GHSA(?:-[0-9a-z]{4}){3}
|
||||||
|
|
||||||
|
# GitHub actions
|
||||||
|
\buses:\s+[-\w.]+/[-\w./]+@[-\w.]+
|
||||||
|
|
||||||
|
# GitLab commit
|
||||||
|
\bgitlab\.[^/\s"]*/\S+/\S+/commit/[0-9a-f]{7,16}#[0-9a-f]{40}\b
|
||||||
|
# GitLab merge requests
|
||||||
|
\bgitlab\.[^/\s"]*/\S+/\S+/-/merge_requests/\d+/diffs#[0-9a-f]{40}\b
|
||||||
|
# GitLab uploads
|
||||||
|
\bgitlab\.[^/\s"]*/uploads/[-a-zA-Z=;:/0-9+]*
|
||||||
|
# GitLab commits
|
||||||
|
\bgitlab\.[^/\s"]*/(?:[^/\s"]+/){2}commits?/[0-9a-f]+\b
|
||||||
|
|
||||||
|
# #includes
|
||||||
|
^\s*#include\s*(?:<.*?>|".*?")
|
||||||
|
|
||||||
|
# #pragma lib
|
||||||
|
^\s*#pragma comment\(lib, ".*?"\)
|
||||||
|
|
||||||
|
# binance
|
||||||
|
accounts\.binance\.com/[a-z/]*oauth/authorize\?[-0-9a-zA-Z&%]*
|
||||||
|
|
||||||
|
# bitbucket diff
|
||||||
|
\bapi\.bitbucket\.org/\d+\.\d+/repositories/(?:[^/\s"]+/){2}diff(?:stat|)(?:/[^/\s"]+){2}:[0-9a-f]+
|
||||||
|
# bitbucket repositories commits
|
||||||
|
\bapi\.bitbucket\.org/\d+\.\d+/repositories/(?:[^/\s"]+/){2}commits?/[0-9a-f]+
|
||||||
|
# bitbucket commits
|
||||||
|
\bbitbucket\.org/(?:[^/\s"]+/){2}commits?/[0-9a-f]+
|
||||||
|
|
||||||
|
# bit.ly
|
||||||
|
\bbit\.ly/\w+
|
||||||
|
|
||||||
|
# bitrise
|
||||||
|
\bapp\.bitrise\.io/app/[0-9a-f]*/[\w.?=&]*
|
||||||
|
|
||||||
|
# bootstrapcdn.com
|
||||||
|
\bbootstrapcdn\.com/[-./\w]+
|
||||||
|
|
||||||
|
# cdn.cloudflare.com
|
||||||
|
\bcdnjs\.cloudflare\.com/[./\w]+
|
||||||
|
|
||||||
|
# circleci
|
||||||
|
\bcircleci\.com/gh(?:/[^/\s"]+){1,5}.[a-z]+\?[-0-9a-zA-Z=&]+
|
||||||
|
|
||||||
|
# gitter
|
||||||
|
\bgitter\.im(?:/[^/\s"]+){2}\?at=[0-9a-f]+
|
||||||
|
|
||||||
|
# gravatar
|
||||||
|
\bgravatar\.com/avatar/[0-9a-f]+
|
||||||
|
|
||||||
|
# ibm
|
||||||
|
[a-z.]*ibm\.com/[-_#=:%!?~.\\/\d\w]*
|
||||||
|
|
||||||
|
# imgur
|
||||||
|
\bimgur\.com/[^.]+
|
||||||
|
|
||||||
|
# Internet Archive
|
||||||
|
\barchive\.org/web/\d+/(?:[-\w.?,'/\\+&%$#_:]*)
|
||||||
|
|
||||||
|
# discord
|
||||||
|
/discord(?:app\.com|\.gg)/(?:invite/)?[a-zA-Z0-9]{7,}
|
||||||
|
|
||||||
|
# Disqus
|
||||||
|
\bdisqus\.com/[-\w/%.()!?&=_]*
|
||||||
|
|
||||||
|
# medium link
|
||||||
|
\blink\.medium\.com/[a-zA-Z0-9]+
|
||||||
|
# medium
|
||||||
|
\bmedium\.com/@?[^/\s"]+/[-\w]+
|
||||||
|
|
||||||
|
# microsoft
|
||||||
|
\b(?:https?://|)(?:(?:(?:blogs|download\.visualstudio|docs|msdn2?|research)\.|)microsoft|blogs\.msdn)\.co(?:m|\.\w\w)/[-_a-zA-Z0-9()=./%]*
|
||||||
|
# powerbi
|
||||||
|
\bapp\.powerbi\.com/reportEmbed/[^"' ]*
|
||||||
|
# vs devops
|
||||||
|
\bvisualstudio.com(?::443|)/[-\w/?=%&.]*
|
||||||
|
# microsoft store
|
||||||
|
\bmicrosoft\.com/store/apps/\w+
|
||||||
|
|
||||||
|
# mvnrepository.com
|
||||||
|
\bmvnrepository\.com/[-0-9a-z./]+
|
||||||
|
|
||||||
|
# now.sh
|
||||||
|
/[0-9a-z-.]+\.now\.sh\b
|
||||||
|
|
||||||
|
# oracle
|
||||||
|
\bdocs\.oracle\.com/[-0-9a-zA-Z./_?#&=]*
|
||||||
|
|
||||||
|
# chromatic.com
|
||||||
|
/\S+.chromatic.com\S*[")]
|
||||||
|
|
||||||
|
# codacy
|
||||||
|
\bapi\.codacy\.com/project/badge/Grade/[0-9a-f]+
|
||||||
|
|
||||||
|
# compai
|
||||||
|
\bcompai\.pub/v1/png/[0-9a-f]+
|
||||||
|
|
||||||
|
# mailgun api
|
||||||
|
\.api\.mailgun\.net/v3/domains/[0-9a-z]+\.mailgun.org/messages/[0-9a-zA-Z=@]*
|
||||||
|
# mailgun
|
||||||
|
\b[0-9a-z]+.mailgun.org
|
||||||
|
|
||||||
|
# /message-id/
|
||||||
|
/message-id/[-\w@./%]+
|
||||||
|
|
||||||
|
# Reddit
|
||||||
|
\breddit\.com/r/[/\w_]*
|
||||||
|
|
||||||
|
# requestb.in
|
||||||
|
\brequestb\.in/[0-9a-z]+
|
||||||
|
|
||||||
|
# sched
|
||||||
|
\b[a-z0-9]+\.sched\.com\b
|
||||||
|
|
||||||
|
# Slack url
|
||||||
|
slack://[a-zA-Z0-9?&=]+
|
||||||
|
# Slack
|
||||||
|
\bslack\.com/[-0-9a-zA-Z/_~?&=.]*
|
||||||
|
# Slack edge
|
||||||
|
\bslack-edge\.com/[-a-zA-Z0-9?&=%./]+
|
||||||
|
# Slack images
|
||||||
|
\bslack-imgs\.com/[-a-zA-Z0-9?&=%.]+
|
||||||
|
|
||||||
|
# shields.io
|
||||||
|
\bshields\.io/[-\w/%?=&.:+;,]*
|
||||||
|
|
||||||
|
# stackexchange -- https://stackexchange.com/feeds/sites
|
||||||
|
\b(?:askubuntu|serverfault|stack(?:exchange|overflow)|superuser).com/(?:questions/\w+/[-\w]+|a/)
|
||||||
|
|
||||||
|
# Sentry
|
||||||
|
[0-9a-f]{32}\@o\d+\.ingest\.sentry\.io\b
|
||||||
|
|
||||||
|
# Twitter markdown
|
||||||
|
\[@[^[/\]:]*?\]\(https://twitter.com/[^/\s"')]*(?:/status/\d+(?:\?[-_0-9a-zA-Z&=]*|)|)\)
|
||||||
|
# Twitter hashtag
|
||||||
|
\btwitter\.com/hashtag/[\w?_=&]*
|
||||||
|
# Twitter status
|
||||||
|
\btwitter\.com/[^/\s"')]*(?:/status/\d+(?:\?[-_0-9a-zA-Z&=]*|)|)
|
||||||
|
# Twitter profile images
|
||||||
|
\btwimg\.com/profile_images/[_\w./]*
|
||||||
|
# Twitter media
|
||||||
|
\btwimg\.com/media/[-_\w./?=]*
|
||||||
|
# Twitter link shortened
|
||||||
|
\bt\.co/\w+
|
||||||
|
|
||||||
|
# facebook
|
||||||
|
\bfburl\.com/[0-9a-z_]+
|
||||||
|
# facebook CDN
|
||||||
|
\bfbcdn\.net/[\w/.,]*
|
||||||
|
# facebook watch
|
||||||
|
\bfb\.watch/[0-9A-Za-z]+
|
||||||
|
|
||||||
|
# dropbox
|
||||||
|
\bdropbox\.com/sh?/[^/\s"]+/[-0-9A-Za-z_.%?=&;]+
|
||||||
|
|
||||||
|
# ipfs protocol
|
||||||
|
ipfs://[0-9a-zA-Z]{3,}
|
||||||
|
# ipfs url
|
||||||
|
/ipfs/[0-9a-zA-Z]{3,}
|
||||||
|
|
||||||
|
# w3
|
||||||
|
\bw3\.org/[-0-9a-zA-Z/#.]+
|
||||||
|
|
||||||
|
# loom
|
||||||
|
\bloom\.com/embed/[0-9a-f]+
|
||||||
|
|
||||||
|
# regex101
|
||||||
|
\bregex101\.com/r/[^/\s"]+/\d+
|
||||||
|
|
||||||
|
# figma
|
||||||
|
\bfigma\.com/file(?:/[0-9a-zA-Z]+/)+
|
||||||
|
|
||||||
|
# freecodecamp.org
|
||||||
|
\bfreecodecamp\.org/[-\w/.]+
|
||||||
|
|
||||||
|
# image.tmdb.org
|
||||||
|
\bimage\.tmdb\.org/[/\w.]+
|
||||||
|
|
||||||
|
# mermaid
|
||||||
|
\bmermaid\.ink/img/[-\w]+|\bmermaid-js\.github\.io/mermaid-live-editor/#/edit/[-\w]+
|
||||||
|
|
||||||
|
# Wikipedia
|
||||||
|
\ben\.wikipedia\.org/wiki/[-\w%.#]+
|
||||||
|
|
||||||
|
# gitweb
|
||||||
|
[^"\s]+/gitweb/\S+;h=[0-9a-f]+
|
||||||
|
|
||||||
|
# HyperKitty lists
|
||||||
|
/archives/list/[^@/]+@[^/\s"]*/message/[^/\s"]*/
|
||||||
|
|
||||||
|
# lists
|
||||||
|
/thread\.html/[^"\s]+
|
||||||
|
|
||||||
|
# list-management
|
||||||
|
\blist-manage\.com/subscribe(?:[?&](?:u|id)=[0-9a-f]+)+
|
||||||
|
|
||||||
|
# kubectl.kubernetes.io/last-applied-configuration
|
||||||
|
"kubectl.kubernetes.io/last-applied-configuration": ".*"
|
||||||
|
|
||||||
|
# pgp
|
||||||
|
\bgnupg\.net/pks/lookup[?&=0-9a-zA-Z]*
|
||||||
|
|
||||||
|
# Spotify
|
||||||
|
\bopen\.spotify\.com/embed/playlist/\w+
|
||||||
|
|
||||||
|
# Mastodon
|
||||||
|
\bmastodon\.[-a-z.]*/(?:media/|@)[?&=0-9a-zA-Z_]*
|
||||||
|
|
||||||
|
# scastie
|
||||||
|
\bscastie\.scala-lang\.org/[^/]+/\w+
|
||||||
|
|
||||||
|
# images.unsplash.com
|
||||||
|
\bimages\.unsplash\.com/(?:(?:flagged|reserve)/|)[-\w./%?=%&.;]+
|
||||||
|
|
||||||
|
# pastebin
|
||||||
|
\bpastebin\.com/[\w/]+
|
||||||
|
|
||||||
|
# heroku
|
||||||
|
\b\w+\.heroku\.com/source/archive/\w+
|
||||||
|
|
||||||
|
# quip
|
||||||
|
\b\w+\.quip\.com/\w+(?:(?:#|/issues/)\w+)?
|
||||||
|
|
||||||
|
# badgen.net
|
||||||
|
\bbadgen\.net/badge/[^")\]'\s]+
|
||||||
|
|
||||||
|
# statuspage.io
|
||||||
|
\w+\.statuspage\.io\b
|
||||||
|
|
||||||
|
# media.giphy.com
|
||||||
|
\bmedia\.giphy\.com/media/[^/]+/[\w.?&=]+
|
||||||
|
|
||||||
|
# tinyurl
|
||||||
|
\btinyurl\.com/\w+
|
||||||
|
|
||||||
|
# codepen
|
||||||
|
\bcodepen\.io/[\w/]+
|
||||||
|
|
||||||
|
# registry.npmjs.org
|
||||||
|
\bregistry\.npmjs\.org/(?:@[^/"']+/|)[^/"']+/-/[-\w@.]+
|
||||||
|
|
||||||
|
# getopts
|
||||||
|
\bgetopts\s+(?:"[^"]+"|'[^']+')
|
||||||
|
|
||||||
|
# ANSI color codes
|
||||||
|
(?:\\(?:u00|x)1[Bb]|\\03[1-7]|\x1b|\\u\{1[Bb]\})\[\d+(?:;\d+)*m
|
||||||
|
|
||||||
|
# URL escaped characters
|
||||||
|
%[0-9A-F][A-F](?=[A-Za-z])
|
||||||
|
# lower URL escaped characters
|
||||||
|
%[0-9a-f][a-f](?=[a-z]{2,})
|
||||||
|
# IPv6
|
||||||
|
\b(?:[0-9a-fA-F]{0,4}:){3,7}[0-9a-fA-F]{0,4}\b
|
||||||
|
# c99 hex digits (not the full format, just one I've seen)
|
||||||
|
0x[0-9a-fA-F](?:\.[0-9a-fA-F]*|)[pP]
|
||||||
|
# Punycode
|
||||||
|
\bxn--[-0-9a-z]+
|
||||||
|
# sha
|
||||||
|
sha\d+:[0-9a-f]*?[a-f]{3,}[0-9a-f]*
|
||||||
|
# sha-... -- uses a fancy capture
|
||||||
|
(\\?['"]|")[0-9a-f]{40,}\g{-1}
|
||||||
|
# hex runs
|
||||||
|
\b[0-9a-fA-F]{16,}\b
|
||||||
|
# hex in url queries
|
||||||
|
=[0-9a-fA-F]*?(?:[A-F]{3,}|[a-f]{3,})[0-9a-fA-F]*?&
|
||||||
|
# ssh
|
||||||
|
(?:ssh-\S+|-nistp256) [-a-zA-Z=;:/0-9+]{12,}
|
||||||
|
|
||||||
|
# PGP
|
||||||
|
\b(?:[0-9A-F]{4} ){9}[0-9A-F]{4}\b
|
||||||
|
# GPG keys
|
||||||
|
\b(?:[0-9A-F]{4} ){5}(?: [0-9A-F]{4}){5}\b
|
||||||
|
# Well known gpg keys
|
||||||
|
.well-known/openpgpkey/[\w./]+
|
||||||
|
|
||||||
|
# pki
|
||||||
|
-----BEGIN.*-----END
|
||||||
|
|
||||||
|
# pki (base64)
|
||||||
|
LS0tLS1CRUdJT.*
|
||||||
|
|
||||||
|
# C# includes
|
||||||
|
^\s*using [^;]+;
|
||||||
|
|
||||||
|
# uuid:
|
||||||
|
\b[0-9a-fA-F]{8}-(?:[0-9a-fA-F]{4}-){3}[0-9a-fA-F]{12}\b
|
||||||
|
# hex digits including css/html color classes:
|
||||||
|
(?:[\\0][xX]|\\u|[uU]\+|#x?|%23|&H)[0-9_a-fA-FgGrR]*?[a-fA-FgGrR]{2,}[0-9_a-fA-FgGrR]*(?:[uUlL]{0,3}|[iu]\d+)\b
|
||||||
|
|
||||||
|
# integrity
|
||||||
|
integrity=(['"])(?:\s*sha\d+-[-a-zA-Z=;:/0-9+]{40,})+\g{-1}
|
||||||
|
|
||||||
|
# https://www.gnu.org/software/groff/manual/groff.html
|
||||||
|
# man troff content
|
||||||
|
\\f[BCIPR]
|
||||||
|
# '/"
|
||||||
|
\\\([ad]q
|
||||||
|
|
||||||
|
# .desktop mime types
|
||||||
|
^MimeTypes?=.*$
|
||||||
|
# .desktop localized entries
|
||||||
|
^[A-Z][a-z]+\[[a-z]+\]=.*$
|
||||||
|
# Localized .desktop content
|
||||||
|
Name\[[^\]]+\]=.*
|
||||||
|
|
||||||
|
# IServiceProvider / isAThing
|
||||||
|
(?:(?:\b|_|(?<=[a-z]))I|(?:\b|_)(?:nsI|isA))(?=(?:[A-Z][a-z]{2,})+(?:[A-Z\d]|\b))
|
||||||
|
|
||||||
|
# crypt
|
||||||
|
(['"])\$2[ayb]\$.{56}\g{-1}
|
||||||
|
|
||||||
|
# apache/old crypt
|
||||||
|
(['"]|)\$+(?:apr|)1\$+.{8}\$+.{22}\g{-1}
|
||||||
|
|
||||||
|
# sha1 hash
|
||||||
|
\{SHA\}[-a-zA-Z=;:/0-9+]{3,}
|
||||||
|
|
||||||
|
# machine learning (?)
|
||||||
|
\b(?i)ml(?=[a-z]{2,})
|
||||||
|
|
||||||
|
# python
|
||||||
|
#\b(?i)py(?!gments|gmy|lon|ramid|ro|th)(?=[a-z]{2,})
|
||||||
|
|
||||||
|
# scrypt / argon
|
||||||
|
\$(?:scrypt|argon\d+[di]*)\$\S+
|
||||||
|
|
||||||
|
# go.sum
|
||||||
|
\bh1:\S+
|
||||||
|
|
||||||
|
# imports
|
||||||
|
^import\s+(?:(?:static|type)\s+|)(?:[\w.]|\{\s*\w*?(?:,\s*(?:\w*|\*))+\s*\})+
|
||||||
|
|
||||||
|
# scala modules
|
||||||
|
("[^"]+"\s*%%?\s*){2,3}"[^"]+"
|
||||||
|
|
||||||
|
# container images
|
||||||
|
image: [-\w./:@]+
|
||||||
|
|
||||||
|
# Docker images
|
||||||
|
^\s*(?i)FROM\s+\S+:\S+(?:\s+AS\s+\S+|)
|
||||||
|
|
||||||
|
# `docker images` REPOSITORY TAG IMAGE ID CREATED SIZE
|
||||||
|
\s*\S+/\S+\s+\S+\s+[0-9a-f]{8,}\s+\d+\s+(?:hour|day|week)s ago\s+[\d.]+[KMGT]B
|
||||||
|
|
||||||
|
# Intel intrinsics
|
||||||
|
_mm_(?!dd)\w+
|
||||||
|
|
||||||
|
# Input to GitHub JSON
|
||||||
|
content: (['"])[-a-zA-Z=;:/0-9+]*=\g{-1}
|
||||||
|
|
||||||
|
# This does not cover multiline strings, if your repository has them,
|
||||||
|
# you'll want to remove the `(?=.*?")` suffix.
|
||||||
|
# The `(?=.*?")` suffix should limit the false positives rate
|
||||||
|
# printf
|
||||||
|
%(?:(?:(?:hh?|ll?|[jzt])?[diuoxn]|l?[cs]|L?[fega]|p)(?=[a-z]{2,})|(?:X|L?[FEGA])(?=[a-zA-Z]{2,}))(?!%)(?=[_a-zA-Z]+(?!%)\b)(?=.*?['"])
|
||||||
|
|
||||||
|
# Alternative printf
|
||||||
|
# %s
|
||||||
|
%(?:s(?=[a-z]{2,}))(?!%)(?=[_a-zA-Z]+(?!%[^s])\b)(?=.*?['"])
|
||||||
|
|
||||||
|
# Python string prefix / binary prefix
|
||||||
|
# Note that there's a high false positive rate, remove the `?=` and search for the regex to see if the matches seem like reasonable strings
|
||||||
|
(?<!['"])\b(?:B|BR|Br|F|FR|Fr|R|RB|RF|Rb|Rf|U|UR|Ur|b|bR|br|f|fR|fr|r|rB|rF|rb|rf|u|uR|ur)['"](?=[A-Z]{3,}|[A-Z][a-z]{2,}|[a-z]{3,})
|
||||||
|
|
||||||
|
# Regular expressions for (P|p)assword
|
||||||
|
\([A-Z]\|[a-z]\)[a-z]+
|
||||||
|
|
||||||
|
# JavaScript regular expressions
|
||||||
|
# javascript test regex
|
||||||
|
/.{3,}/[gim]*\.test\(
|
||||||
|
# javascript match regex
|
||||||
|
\.match\(/[^/\s"]{3,}/[gim]*\s*
|
||||||
|
# javascript match regex
|
||||||
|
\.match\(/\\[b].{3,}?/[gim]*\s*\)(?:;|$)
|
||||||
|
# javascript regex
|
||||||
|
^\s*/\\[b].{3,}?/[gim]*\s*(?:\)(?:;|$)|,$)
|
||||||
|
# javascript replace regex
|
||||||
|
\.replace\(/[^/\s"]{3,}/[gim]*\s*,
|
||||||
|
# assign regex
|
||||||
|
= /[^*].*?(?:[a-z]{3,}|[A-Z]{3,}|[A-Z][a-z]{2,}).*/[gim]*(?=\W|$)
|
||||||
|
# perl regex test
|
||||||
|
[!=]~ (?:/.*/|m\{.*?\}|m<.*?>|m([|!/@#,;']).*?\g{-1})
|
||||||
|
|
||||||
|
# perl qr regex
|
||||||
|
(?<!\$)\bqr(?:\{.*?\}|<.*?>|\(.*?\)|([|!/@#,;']).*?\g{-1})
|
||||||
|
|
||||||
|
# perl run
|
||||||
|
perl(?:\s+-[a-zA-Z]\w*)+
|
||||||
|
|
||||||
|
# C network byte conversions
|
||||||
|
(?:\d|\bh)to(?!ken)(?=[a-z])|to(?=[adhiklpun]\()
|
||||||
|
|
||||||
|
# Go regular expressions
|
||||||
|
regexp?\.MustCompile\((?:`[^`]*`|".*"|'.*')\)
|
||||||
|
|
||||||
|
# regex choice
|
||||||
|
\(\?:[^)]+\|[^)]+\)
|
||||||
|
|
||||||
|
# proto
|
||||||
|
^\s*(\w+)\s\g{-1} =
|
||||||
|
|
||||||
|
# sed regular expressions
|
||||||
|
sed 's/(?:[^/]*?[a-zA-Z]{3,}[^/]*?/){2}
|
||||||
|
|
||||||
|
# node packages
|
||||||
|
(["'])@[^/'" ]+/[^/'" ]+\g{-1}
|
||||||
|
|
||||||
|
# go install
|
||||||
|
go install(?:\s+[a-z]+\.[-@\w/.]+)+
|
||||||
|
|
||||||
|
# pom.xml
|
||||||
|
<(?:group|artifact)Id>.*?<
|
||||||
|
|
||||||
|
# jetbrains schema https://youtrack.jetbrains.com/issue/RSRP-489571
|
||||||
|
urn:shemas-jetbrains-com
|
||||||
|
|
||||||
|
# Debian changelog severity
|
||||||
|
[-\w]+ \(.*\) (?:\w+|baseline|unstable|experimental); urgency=(?:low|medium|high|emergency|critical)\b
|
||||||
|
|
||||||
|
# kubernetes pod status lists
|
||||||
|
# https://kubernetes.io/docs/concepts/workloads/pods/pod-lifecycle/#pod-phase
|
||||||
|
\w+(?:-\w+)+\s+\d+/\d+\s+(?:Running|Pending|Succeeded|Failed|Unknown)\s+
|
||||||
|
|
||||||
|
# kubectl - pods in CrashLoopBackOff
|
||||||
|
\w+-[0-9a-f]+-\w+\s+\d+/\d+\s+CrashLoopBackOff\s+
|
||||||
|
|
||||||
|
# kubernetes applications
|
||||||
|
\.apps/[-\w]+
|
||||||
|
|
||||||
|
# kubernetes object suffix
|
||||||
|
-[0-9a-f]{10}-\w{5}\s
|
||||||
|
|
||||||
|
# kubernetes crd patterns
|
||||||
|
^\s*pattern: .*$
|
||||||
|
|
||||||
|
# posthog secrets
|
||||||
|
([`'"])phc_[^"',]+\g{-1}
|
||||||
|
|
||||||
|
# xcode
|
||||||
|
|
||||||
|
# xcodeproject scenes
|
||||||
|
(?:Controller|destination|(?:first|second)Item|ID|id)="\w{3}-\w{2}-\w{3}"
|
||||||
|
|
||||||
|
# xcode api botches
|
||||||
|
customObjectInstantitationMethod
|
||||||
|
|
||||||
|
# msvc api botches
|
||||||
|
PrependWithABINamepsace
|
||||||
|
|
||||||
|
# configure flags
|
||||||
|
.* \| --\w{2,}.*?(?=\w+\s\w+)
|
||||||
|
|
||||||
|
# font awesome classes
|
||||||
|
\.fa-[-a-z0-9]+
|
||||||
|
|
||||||
|
# bearer auth
|
||||||
|
(['"])[Bb]ear[e][r] .{3,}?\g{-1}
|
||||||
|
|
||||||
|
# bearer auth
|
||||||
|
\b[Bb]ear[e][r]:? [-a-zA-Z=;:/0-9+.]{3,}
|
||||||
|
|
||||||
|
# basic auth
|
||||||
|
(['"])[Bb]asic [-a-zA-Z=;:/0-9+]{3,}\g{-1}
|
||||||
|
|
||||||
|
# basic auth
|
||||||
|
: [Bb]asic [-a-zA-Z=;:/0-9+.]{3,}
|
||||||
|
|
||||||
|
# base64 encoded content
|
||||||
|
([`'"])[-a-zA-Z=;:/0-9+]{3,}=\g{-1}
|
||||||
|
# base64 encoded content in xml/sgml
|
||||||
|
>[-a-zA-Z=;:/0-9+]{3,}=</
|
||||||
|
# base64 encoded content, possibly wrapped in mime
|
||||||
|
#(?:^|[\s=;:?])[-a-zA-Z=;:/0-9+]{50,}(?:[\s=;:?]|$)
|
||||||
|
# base64 encoded json
|
||||||
|
\beyJ[-a-zA-Z=;:/0-9+]+
|
||||||
|
# base64 encoded pkcs
|
||||||
|
\bMII[-a-zA-Z=;:/0-9+]+
|
||||||
|
|
||||||
|
# uuencoded
|
||||||
|
#[!"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_]{40,}
|
||||||
|
|
||||||
|
# DNS rr data
|
||||||
|
(?:\d+\s+){3}(?:[-+/=.\w]{2,}\s*){1,2}
|
||||||
|
|
||||||
|
# encoded-word
|
||||||
|
=\?[-a-zA-Z0-9"*%]+\?[BQ]\?[^?]{0,75}\?=
|
||||||
|
|
||||||
|
# numerator
|
||||||
|
\bnumer\b(?=.*denom)
|
||||||
|
|
||||||
|
# Time Zones
|
||||||
|
\b(?:Africa|Atlantic|America|Antarctica|Arctic|Asia|Australia|Europe|Indian|Pacific)(?:/[-\w]+)+
|
||||||
|
|
||||||
|
# linux kernel info
|
||||||
|
^(?:bugs|flags|Features)\s+:.*
|
||||||
|
|
||||||
|
# systemd mode
|
||||||
|
systemd.*?running in system mode \([-+].*\)$
|
||||||
|
|
||||||
|
# Lorem
|
||||||
|
# Update Lorem based on your content (requires `ge` and `w` from https://github.com/jsoref/spelling; and `review` from https://github.com/check-spelling/check-spelling/wiki/Looking-for-items-locally )
|
||||||
|
# grep '^[^#].*lorem' .github/actions/spelling/patterns.txt|perl -pne 's/.*i..\?://;s/\).*//' |tr '|' "\n"|sort -f |xargs -n1 ge|perl -pne 's/^[^:]*://'|sort -u|w|sed -e 's/ .*//'|w|review -
|
||||||
|
# Warning, while `(?i)` is very neat and fancy, if you have some binary files that aren't proper unicode, you might run into:
|
||||||
|
# ... Operation "substitution (s///)" returns its argument for non-Unicode code point 0x1C19AE (the code point will vary).
|
||||||
|
# ... You could manually change `(?i)X...` to use `[Xx]...`
|
||||||
|
# ... or you could add the files to your `excludes` file (a version after 0.0.19 should identify the file path)
|
||||||
|
(?:(?:\w|\s|[,.])*\b(?i)(?:amet|consectetur|cursus|dolor|eros|ipsum|lacus|libero|ligula|lorem|magna|neque|nulla|suscipit|tempus)\b(?:\w|\s|[,.])*)
|
||||||
|
|
||||||
|
# Non-English
|
||||||
|
# Even repositories expecting pure English content can unintentionally have Non-English content... People will occasionally mistakenly enter [homoglyphs](https://en.wikipedia.org/wiki/Homoglyph) which are essentially typos, and using this pattern will mean check-spelling will not complain about them.
|
||||||
|
#
|
||||||
|
# If the content to be checked should be written in English and the only Non-English items will be people's names, then you can consider adding this.
|
||||||
|
#
|
||||||
|
# Alternatively, if you're using check-spelling v0.0.25+, and you would like to _check_ the Non-English content for spelling errors, you can. For information on how to do so, see:
|
||||||
|
# https://docs.check-spelling.dev/Feature:-Configurable-word-characters.html#unicode
|
||||||
|
[a-zA-Z]*[ÀÁÂÃÄÅÆČÇÈÉÊËÌÍÎÏÐÑÒÓÔÕÖØÙÚÛÜÝßàáâãäåæčçèéêëìíîïðñòóôõöøùúûüýÿĀāŁłŃńŅņŒœŚśŠšŜŝŸŽžź][a-zA-Z]{3}[a-zA-ZÀÁÂÃÄÅÆČÇÈÉÊËÌÍÎÏÐÑÒÓÔÕÖØÙÚÛÜÝßàáâãäåæčçèéêëìíîïðñòóôõöøùúûüýÿĀāŁłŃńŅņŒœŚśŠšŜŝŸŽžź]*|[a-zA-Z]{3,}[ÀÁÂÃÄÅÆČÇÈÉÊËÌÍÎÏÐÑÒÓÔÕÖØÙÚÛÜÝßàáâãäåæčçèéêëìíîïðñòóôõöøùúûüýÿĀāŁłŃńŅņŒœŚśŠšŜŝŸŽžź]|[ÀÁÂÃÄÅÆČÇÈÉÊËÌÍÎÏÐÑÒÓÔÕÖØÙÚÛÜÝßàáâãäåæčçèéêëìíîïðñòóôõöøùúûüýÿĀāŁłŃńŅņŒœŚśŠšŜŝŸŽžź][a-zA-Z]{3,}
|
||||||
|
|
||||||
|
# highlighted letters
|
||||||
|
\[[A-Z]\][a-z]+
|
||||||
|
|
||||||
|
# French
|
||||||
|
# This corpus only had capital letters, but you probably want lowercase ones as well.
|
||||||
|
\b[LN]'+[a-z]{2,}\b
|
||||||
|
|
||||||
|
# latex (check-spelling >= 0.0.22)
|
||||||
|
\\\w{2,}\{
|
||||||
|
|
||||||
|
# American Mathematical Society (AMS) / Doxygen
|
||||||
|
TeX/AMS
|
||||||
|
|
||||||
|
# File extensions
|
||||||
|
\*\.[+\w]+,
|
||||||
|
|
||||||
|
# eslint
|
||||||
|
"varsIgnorePattern": ".+"
|
||||||
|
|
||||||
|
# nolint
|
||||||
|
nolint:\s*[\w,]+
|
||||||
|
|
||||||
|
# Windows short paths
|
||||||
|
[/\\][^/\\]{5,6}~\d{1,2}(?=[/\\])
|
||||||
|
|
||||||
|
# Windows Resources with accelerators
|
||||||
|
\b[A-Z]&[a-z]+\b(?!;)
|
||||||
|
|
||||||
|
# signed off by
|
||||||
|
(?i)Signed-off-by: .*
|
||||||
|
|
||||||
|
# cygwin paths
|
||||||
|
/cygdrive/[a-zA-Z]/(?:Program Files(?: \(.*?\)| ?)(?:/[-+.~\\/()\w ]+)*|[-+.~\\/()\w])+
|
||||||
|
|
||||||
|
# in check-spelling@v0.0.22+, printf markers aren't automatically consumed
|
||||||
|
# printf markers
|
||||||
|
(?<!\\)\\[nrt](?=[a-z]{2,})
|
||||||
|
# alternate printf markers if you run into latex and friends
|
||||||
|
(?<!\\)\\[nrt](?=[a-z]{2,})(?=.*['"`])
|
||||||
|
|
||||||
|
# Markdown anchor links
|
||||||
|
\(#\S*?[a-zA-Z]\S*?\)
|
||||||
|
|
||||||
|
# apache
|
||||||
|
a2(?:en|dis)
|
||||||
|
|
||||||
|
# weak e-tag
|
||||||
|
W/"[^"]+"
|
||||||
|
|
||||||
|
# authors/credits
|
||||||
|
^\*(?: [A-Z](?:\w+|\.)){2,} (?=\[|$)
|
||||||
|
|
||||||
|
# the negative lookahead here is to allow catching 'templatesz' as a misspelling
|
||||||
|
# but to otherwise recognize a Windows path with \templates\foo.template or similar:
|
||||||
|
\\(?:necessary|r(?:elease|eport|esolve[dr]?|esult)|t(?:arget|emplates?))(?![a-z])
|
||||||
|
# ignore long runs of a single character:
|
||||||
|
\b([A-Za-z])\g{-1}{3,}\b
|
||||||
|
|
||||||
|
# version suffix <word>v#
|
||||||
|
(?:(?<=[A-Z]{2})V|(?<=[a-z]{2}|[A-Z]{2})v)\d+(?:\b|(?=[a-zA-Z_]))
|
||||||
|
|
||||||
|
# Compiler flags (Unix, Java/Scala)
|
||||||
|
# Use if you have things like `-Pdocker` and want to treat them as `docker`
|
||||||
|
#(?:^|[\t ,>"'`=(#])-(?:(?:J-|)[DPWXY]|[Llf])(?=[A-Z]{2,}|[A-Z][a-z]|[a-z]{2,})
|
||||||
|
|
||||||
|
# Compiler flags (Windows / PowerShell)
|
||||||
|
# This is a subset of the more general compiler flags pattern.
|
||||||
|
# It avoids matching `-Path` to prevent it from being treated as `ath`
|
||||||
|
#(?:^|[\t ,"'`=(#])-(?:[DPL](?=[A-Z]{2,})|[WXYlf](?=[A-Z]{2,}|[A-Z][a-z]|[a-z]{2,}))
|
||||||
|
|
||||||
|
# Compiler flags (linker)
|
||||||
|
,-B
|
||||||
|
|
||||||
|
# libraries
|
||||||
|
(?:\b|_)[Ll]ib(?:re(?=office)|)(?!era[lt]|ero|erty|rar(?:i(?:an|es)|y))(?=[a-z])
|
||||||
|
|
||||||
|
# WWNN/WWPN (NAA identifiers)
|
||||||
|
\b(?:0x)?10[0-9a-f]{14}\b|\b(?:0x|3)?[25][0-9a-f]{15}\b|\b(?:0x|3)?6[0-9a-f]{31}\b
|
||||||
|
|
||||||
|
# iSCSI iqn (approximate regex)
|
||||||
|
\biqn\.[0-9]{4}-[0-9]{2}(?:[\.-][a-z][a-z0-9]*)*\b
|
||||||
|
|
||||||
|
# curl arguments
|
||||||
|
\b(?:\\n|)curl(?:\.exe|)(?:\s+-[a-zA-Z]{1,2}\b)*(?:\s+-[a-zA-Z]{3,})(?:\s+-[a-zA-Z]+)*
|
||||||
|
# set arguments
|
||||||
|
\b(?:bash|sh|set)(?:\s+[-+][abefimouxE]{1,2})*\s+[-+][abefimouxE]{3,}(?:\s+[-+][abefimouxE]+)*
|
||||||
|
# tar arguments
|
||||||
|
\b(?:\\n|)g?tar(?:\.exe|)(?:(?:\s+--[-a-zA-Z]+|\s+-[a-zA-Z]+|\s[ABGJMOPRSUWZacdfh-pr-xz]+\b)(?:=[^ ]*|))+
|
||||||
|
# tput arguments -- https://man7.org/linux/man-pages/man5/terminfo.5.html -- technically they can be more than 5 chars long...
|
||||||
|
\btput\s+(?:(?:-[SV]|-T\s*\w+)\s+)*\w{3,5}\b
|
||||||
|
# macOS temp folders
|
||||||
|
/var/folders/\w\w/[+\w]+/(?:T|-Caches-)/
|
||||||
|
# github runner temp folders
|
||||||
|
/home/runner/work/_temp/[-_/a-z0-9]+
|
||||||
88
.github/actions/spelling/excludes.txt
vendored
Normal file
88
.github/actions/spelling/excludes.txt
vendored
Normal file
@@ -0,0 +1,88 @@
|
|||||||
|
# See https://github.com/check-spelling/check-spelling/wiki/Configuration-Examples:-excludes
|
||||||
|
(?:^|/)(?i)COPYRIGHT
|
||||||
|
(?:^|/)(?i)LICEN[CS]E
|
||||||
|
(?:^|/)(?i)third[-_]?party/
|
||||||
|
(?:^|/)3rdparty/
|
||||||
|
(?:^|/)generated/
|
||||||
|
(?:^|/)go\.sum$
|
||||||
|
(?:^|/)package(?:-lock|)\.json$
|
||||||
|
(?:^|/)Pipfile$
|
||||||
|
(?:^|/)pyproject.toml
|
||||||
|
(?:^|/)vendor/
|
||||||
|
(?:^|/|\b)requirements(?:-dev|-doc|-test|)\.txt$
|
||||||
|
\.a$
|
||||||
|
\.ai$
|
||||||
|
\.all-contributorsrc$
|
||||||
|
\.avi$
|
||||||
|
\.bmp$
|
||||||
|
\.bz2$
|
||||||
|
\.cert?$|\.crt$
|
||||||
|
\.class$
|
||||||
|
\.coveragerc$
|
||||||
|
\.crl$
|
||||||
|
\.csr$
|
||||||
|
\.dll$
|
||||||
|
\.docx?$
|
||||||
|
\.drawio$
|
||||||
|
\.DS_Store$
|
||||||
|
\.eot$
|
||||||
|
\.eps$
|
||||||
|
\.exe$
|
||||||
|
\.gif$
|
||||||
|
\.git-blame-ignore-revs$
|
||||||
|
\.gitattributes$
|
||||||
|
\.gitkeep$
|
||||||
|
\.graffle$
|
||||||
|
\.gz$
|
||||||
|
\.icns$
|
||||||
|
\.ico$
|
||||||
|
\.ipynb$
|
||||||
|
\.jar$
|
||||||
|
\.jks$
|
||||||
|
\.jpe?g$
|
||||||
|
\.key$
|
||||||
|
\.lib$
|
||||||
|
\.lock$
|
||||||
|
\.map$
|
||||||
|
\.min\..
|
||||||
|
\.mo$
|
||||||
|
\.mod$
|
||||||
|
\.mp[34]$
|
||||||
|
\.o$
|
||||||
|
\.ocf$
|
||||||
|
\.otf$
|
||||||
|
\.p12$
|
||||||
|
\.parquet$
|
||||||
|
\.pdf$
|
||||||
|
\.pem$
|
||||||
|
\.pfx$
|
||||||
|
\.png$
|
||||||
|
\.psd$
|
||||||
|
\.pyc$
|
||||||
|
\.pylintrc$
|
||||||
|
\.qm$
|
||||||
|
\.s$
|
||||||
|
\.sig$
|
||||||
|
\.so$
|
||||||
|
\.svgz?$
|
||||||
|
\.sys$
|
||||||
|
\.tar$
|
||||||
|
\.tgz$
|
||||||
|
\.tiff?$
|
||||||
|
\.ttf$
|
||||||
|
\.wav$
|
||||||
|
\.webm$
|
||||||
|
\.webp$
|
||||||
|
\.woff2?$
|
||||||
|
\.xcf$
|
||||||
|
\.xlsx?$
|
||||||
|
\.xpm$
|
||||||
|
\.xz$
|
||||||
|
\.zip$
|
||||||
|
^\.github/actions/spelling/
|
||||||
|
^\Q.github/FUNDING.yml\E$
|
||||||
|
^\Q.github/workflows/spelling.yml\E$
|
||||||
|
^data/crawlers/
|
||||||
|
^docs/static/\.nojekyll$
|
||||||
|
ignore$
|
||||||
|
robots.txt
|
||||||
222
.github/actions/spelling/expect.txt
vendored
Normal file
222
.github/actions/spelling/expect.txt
vendored
Normal file
@@ -0,0 +1,222 @@
|
|||||||
|
aeacus
|
||||||
|
Aibrew
|
||||||
|
alrest
|
||||||
|
amazonbot
|
||||||
|
anthro
|
||||||
|
anubis
|
||||||
|
anubistest
|
||||||
|
archlinux
|
||||||
|
badregexes
|
||||||
|
berr
|
||||||
|
bingbot
|
||||||
|
Bitcoin
|
||||||
|
blogging
|
||||||
|
Bluesky
|
||||||
|
blueskybot
|
||||||
|
boi
|
||||||
|
botnet
|
||||||
|
BPort
|
||||||
|
broked
|
||||||
|
cachebuster
|
||||||
|
Caddyfile
|
||||||
|
caninetools
|
||||||
|
Cardyb
|
||||||
|
celchecker
|
||||||
|
CELPHASE
|
||||||
|
certresolver
|
||||||
|
CGNAT
|
||||||
|
cgr
|
||||||
|
chainguard
|
||||||
|
chall
|
||||||
|
challengemozilla
|
||||||
|
checkresult
|
||||||
|
chen
|
||||||
|
chibi
|
||||||
|
cidranger
|
||||||
|
ckie
|
||||||
|
cloudflare
|
||||||
|
containerbuild
|
||||||
|
coreutils
|
||||||
|
CRDs
|
||||||
|
crt
|
||||||
|
daemonizing
|
||||||
|
DDOS
|
||||||
|
Debian
|
||||||
|
debrpm
|
||||||
|
decaymap
|
||||||
|
decompiling
|
||||||
|
discordapp
|
||||||
|
discordbot
|
||||||
|
distros
|
||||||
|
dnf
|
||||||
|
dnsbl
|
||||||
|
dnserr
|
||||||
|
dracula
|
||||||
|
dronebl
|
||||||
|
droneblresponse
|
||||||
|
duckduckbot
|
||||||
|
ellenjoe
|
||||||
|
enbyware
|
||||||
|
everyones
|
||||||
|
evilbot
|
||||||
|
evilsite
|
||||||
|
expressionorlist
|
||||||
|
extldflags
|
||||||
|
facebookgo
|
||||||
|
fastcgi
|
||||||
|
fediverse
|
||||||
|
finfos
|
||||||
|
flagenv
|
||||||
|
Fordola
|
||||||
|
forgejo
|
||||||
|
fsys
|
||||||
|
fullchain
|
||||||
|
Galvus
|
||||||
|
gha
|
||||||
|
gitea
|
||||||
|
goland
|
||||||
|
gomod
|
||||||
|
goodbot
|
||||||
|
googlebot
|
||||||
|
govulncheck
|
||||||
|
GPG
|
||||||
|
Hashcash
|
||||||
|
hashrate
|
||||||
|
headermap
|
||||||
|
healthcheck
|
||||||
|
hec
|
||||||
|
hmc
|
||||||
|
hostable
|
||||||
|
httpdebug
|
||||||
|
iat
|
||||||
|
ifm
|
||||||
|
inp
|
||||||
|
iss
|
||||||
|
ivh
|
||||||
|
JGit
|
||||||
|
journalctl
|
||||||
|
jshelter
|
||||||
|
JWTs
|
||||||
|
kagi
|
||||||
|
kagibot
|
||||||
|
keikaku
|
||||||
|
keypair
|
||||||
|
KHTML
|
||||||
|
kinda
|
||||||
|
KUBECONFIG
|
||||||
|
ldflags
|
||||||
|
letsencrypt
|
||||||
|
lgbt
|
||||||
|
licend
|
||||||
|
licstart
|
||||||
|
lightpanda
|
||||||
|
Linting
|
||||||
|
linuxbrew
|
||||||
|
LLU
|
||||||
|
loadbalancer
|
||||||
|
lol
|
||||||
|
maintainership
|
||||||
|
malware
|
||||||
|
mcr
|
||||||
|
memes
|
||||||
|
mimi
|
||||||
|
minica
|
||||||
|
Mojeek
|
||||||
|
mojeekbot
|
||||||
|
mozilla
|
||||||
|
nbf
|
||||||
|
nginx
|
||||||
|
nobots
|
||||||
|
NONINFRINGEMENT
|
||||||
|
nosleep
|
||||||
|
ogtags
|
||||||
|
onionservice
|
||||||
|
pag
|
||||||
|
parseable
|
||||||
|
passthrough
|
||||||
|
Patreon
|
||||||
|
pgrep
|
||||||
|
phrik
|
||||||
|
pidfile
|
||||||
|
pids
|
||||||
|
pipefail
|
||||||
|
pki
|
||||||
|
podkova
|
||||||
|
podman
|
||||||
|
prebaked
|
||||||
|
privkey
|
||||||
|
promauto
|
||||||
|
promhttp
|
||||||
|
pwcmd
|
||||||
|
pwuser
|
||||||
|
qwant
|
||||||
|
qwantbot
|
||||||
|
rac
|
||||||
|
rcvar
|
||||||
|
redir
|
||||||
|
redirectscheme
|
||||||
|
relayd
|
||||||
|
reputational
|
||||||
|
reqmeta
|
||||||
|
risc
|
||||||
|
ruleset
|
||||||
|
RUnlock
|
||||||
|
sas
|
||||||
|
Scumm
|
||||||
|
sebest
|
||||||
|
secretplans
|
||||||
|
selfsigned
|
||||||
|
setsebool
|
||||||
|
sitemap
|
||||||
|
Sourceware
|
||||||
|
Spambot
|
||||||
|
sparkline
|
||||||
|
srv
|
||||||
|
stackoverflow
|
||||||
|
startprecmd
|
||||||
|
stoppostcmd
|
||||||
|
subgrid
|
||||||
|
subr
|
||||||
|
subrequest
|
||||||
|
tagline
|
||||||
|
tarballs
|
||||||
|
techaro
|
||||||
|
techarohq
|
||||||
|
templ
|
||||||
|
templruntime
|
||||||
|
testarea
|
||||||
|
torproject
|
||||||
|
traefik
|
||||||
|
unixhttpd
|
||||||
|
unmarshal
|
||||||
|
uvx
|
||||||
|
Varis
|
||||||
|
vendored
|
||||||
|
vhosts
|
||||||
|
videotest
|
||||||
|
waitloop
|
||||||
|
weblate
|
||||||
|
webmaster
|
||||||
|
webpage
|
||||||
|
websecure
|
||||||
|
websites
|
||||||
|
workaround
|
||||||
|
workdir
|
||||||
|
xcaddy
|
||||||
|
Xeact
|
||||||
|
xeiaso
|
||||||
|
xeserv
|
||||||
|
xesite
|
||||||
|
xess
|
||||||
|
xff
|
||||||
|
XForwarded
|
||||||
|
XReal
|
||||||
|
yae
|
||||||
|
YAMLTo
|
||||||
|
yeet
|
||||||
|
yeetfile
|
||||||
|
yourdomain
|
||||||
|
yoursite
|
||||||
|
Zenos
|
||||||
|
zizmor
|
||||||
|
zos
|
||||||
474
.github/actions/spelling/line_forbidden.patterns
vendored
Normal file
474
.github/actions/spelling/line_forbidden.patterns
vendored
Normal file
@@ -0,0 +1,474 @@
|
|||||||
|
# reject `m_data` as VxWorks defined it and that breaks things if it's used elsewhere
|
||||||
|
# see [fprime](https://github.com/nasa/fprime/commit/d589f0a25c59ea9a800d851ea84c2f5df02fb529)
|
||||||
|
# and [Qt](https://github.com/qtproject/qt-solutions/blame/fb7bc42bfcc578ff3fa3b9ca21a41e96eb37c1c7/qtscriptclassic/src/qscriptbuffer_p.h#L46)
|
||||||
|
#\bm_data\b
|
||||||
|
|
||||||
|
# Were you debugging using a framework with `fit()`?
|
||||||
|
# If you have a framework that uses `it()` for testing and `fit()` for debugging a specific test,
|
||||||
|
# you might not want to check in code where you skip all the other tests.
|
||||||
|
#\bfit\(
|
||||||
|
|
||||||
|
# English does not use a hyphen between adverbs and nouns
|
||||||
|
# https://twitter.com/nyttypos/status/1894815686192685239
|
||||||
|
(?:^|\s)[A-Z]?[a-z]+ly-(?=[a-z]{3,})(?:[.,?!]?\s|$)
|
||||||
|
|
||||||
|
# Don't use `requires that` + `to be`
|
||||||
|
# https://twitter.com/nyttypos/status/1894816551435641027
|
||||||
|
\brequires that \w+\b[^.]+to be\b
|
||||||
|
|
||||||
|
# A fully parenthetical sentence’s period goes inside the parentheses, not outside.
|
||||||
|
# https://twitter.com/nyttypos/status/1898844061873639490
|
||||||
|
#\([A-Z][a-z]{2,}(?: [a-z]+){3,}\)\.\s
|
||||||
|
|
||||||
|
# Complete sentences shouldn't be in the middle of another sentence as a parenthetical.
|
||||||
|
(?<!\.)\.\),
|
||||||
|
|
||||||
|
# Complete sentences in parentheticals should not have a space before the period.
|
||||||
|
\s\.\)(?!.*\}\})
|
||||||
|
|
||||||
|
# Should be `HH:MM:SS`
|
||||||
|
\bHH:SS:MM\b
|
||||||
|
|
||||||
|
# Should be `86400` (seconds in a standard day)
|
||||||
|
\b84600\b(?:.*\bday\b)
|
||||||
|
|
||||||
|
# Should probably be `2006-01-02` (yyyy-mm-dd)
|
||||||
|
# Assuming that the time is being passed to https://go.dev/src/time/format.go
|
||||||
|
\b2006-02-01\b
|
||||||
|
|
||||||
|
# Should probably be `YYYYMMDD`
|
||||||
|
\b[Yy]{4}[Dd]{2}[Mm]{2}(?!.*[Yy]{4}[Dd]{2}[Mm]{2}).*$
|
||||||
|
|
||||||
|
# Should be `a priori` or `and prior`
|
||||||
|
(?i)(?<!posteriori)\sand priori\s
|
||||||
|
|
||||||
|
# Should be `a`
|
||||||
|
\san (?=(?:[b-df-gj-np-rtv-xz]|h(?!our|tml|ttp)|s(?!sh|vg))[a-z])
|
||||||
|
|
||||||
|
# Should only be one of `a`, `an`, or `the`
|
||||||
|
\b(?:(?:an?|the)\s+){2,}\b
|
||||||
|
|
||||||
|
# Should only be `are` or `can`, not both
|
||||||
|
\b(?:(?:are|can)\s+){2,}\b
|
||||||
|
|
||||||
|
# Should probably be `ABCDEFGHIJKLMNOPQRSTUVWXYZ`
|
||||||
|
(?i)(?!ABCDEFGHIJKLMNOPQRSTUVWXYZ)ABC[A-Z]{21}YZ
|
||||||
|
|
||||||
|
# Should be `anymore`
|
||||||
|
\bany more[,.]
|
||||||
|
|
||||||
|
# Should be `Ask`
|
||||||
|
(?:^|[.?]\s+)As\s+[A-Z][a-z]{2,}\s[^.?]*?(?:how|if|wh\w+)\b
|
||||||
|
|
||||||
|
# Should be `at one fell swoop`
|
||||||
|
# and only when talking about killing, not some other completion
|
||||||
|
# Act 4 Scene 3, Macbeth
|
||||||
|
# https://www.opensourceshakespeare.org/views/plays/play_view.php?WorkID=macbeth&Act=4&Scene=3&Scope=scene
|
||||||
|
\bin one fell s[lw]?oop\b
|
||||||
|
|
||||||
|
# Should be `'`
|
||||||
|
(?i)\b(?:(?:i|s?he|they|what|who|you)[`"]ll|(?:are|ca|did|do|does|ha[ds]|have|is|should|were|wo|would)n[`"]t|(?:s?he|let|that|there|what|where|who)[`"]s|(?:i|they|we|what|who|you)[`"]ve)\b
|
||||||
|
|
||||||
|
# Should be `background` / `intro text` / `introduction` / `prologue` unless it's a brand or relates to _subterfuge_
|
||||||
|
(?i)\bpretext\b
|
||||||
|
|
||||||
|
# Should be `branches`
|
||||||
|
# ... unless it's really about the meal that replaces breakfast and lunch.
|
||||||
|
\b[Bb]runches\b
|
||||||
|
|
||||||
|
# Should be `briefcase`
|
||||||
|
\bbrief-case\b
|
||||||
|
|
||||||
|
# Should be `by far` or `far and away`
|
||||||
|
\bby far and away\b
|
||||||
|
|
||||||
|
# Should be `can, not only ..., ... also...`
|
||||||
|
\bcan not only.*can also\b
|
||||||
|
|
||||||
|
# Should be `cannot` (or `can't`)
|
||||||
|
# See https://www.grammarly.com/blog/cannot-or-can-not/
|
||||||
|
# > Don't use `can not` when you mean `cannot`. The only time you're likely to see `can not` written as separate words is when the word `can` happens to precede some other phrase that happens to start with `not`.
|
||||||
|
# > `Can't` is a contraction of `cannot`, and it's best suited for informal writing.
|
||||||
|
# > In formal writing and where contractions are frowned upon, use `cannot`.
|
||||||
|
# > It is possible to write `can not`, but you generally find it only as part of some other construction, such as `not only . . . but also.`
|
||||||
|
# - if you encounter such a case, add a pattern for that case to patterns.txt.
|
||||||
|
\b[Cc]an not\b(?! only\b)
|
||||||
|
|
||||||
|
# Should be `chart`
|
||||||
|
(?i)\bhelm\b.*\bchard\b
|
||||||
|
|
||||||
|
# Do not use `(click) here` links
|
||||||
|
# For more information, see:
|
||||||
|
# * https://www.w3.org/QA/Tips/noClickHere
|
||||||
|
# * https://webaim.org/techniques/hypertext/link_text
|
||||||
|
# * https://granicus.com/blog/why-click-here-links-are-bad/
|
||||||
|
# * https://heyoka.medium.com/dont-use-click-here-f32f445d1021
|
||||||
|
(?i)(?:>|\[)(?:(?:click |)here|link|(?:read |)more)(?:</|\]\()
|
||||||
|
|
||||||
|
# Including "image of" or "picture of" in alt text is unnecessary.
|
||||||
|
\balt=['"](?:an? |)(?:image|picture) of
|
||||||
|
|
||||||
|
# Alt text should be short
|
||||||
|
\balt=(?:'[^']{126,}'|"[^"]{126,}")
|
||||||
|
|
||||||
|
# Should be `equals` to `is equal to`
|
||||||
|
\bequals to\b
|
||||||
|
|
||||||
|
# Should be `ECMA` 262 (JavaScript)
|
||||||
|
(?i)\bTS\/EMCA\b|\bEMCA(?: \d|\s*Script)|\bEMCA\b(?=.*\bTS\b)
|
||||||
|
|
||||||
|
# Should be `ECMA` 340 (Near Field Communications)
|
||||||
|
(?i)EMCA[- ]340
|
||||||
|
|
||||||
|
# Should be `fall back`
|
||||||
|
\bfallback(?= to)\b
|
||||||
|
|
||||||
|
# Should be `GitHub`
|
||||||
|
(?<![&*.]|// |\b(?:from|import|type) )\bGithub\b(?![{()])
|
||||||
|
|
||||||
|
# Should be `GitLab`
|
||||||
|
(?<![&*.]|// |\b(?:from|import|type) )\bGitlab\b(?![{()])
|
||||||
|
|
||||||
|
# Should probably be `https://`...
|
||||||
|
# Markdown generally doesn't assume that links are to urls
|
||||||
|
\]\(www\.\w
|
||||||
|
|
||||||
|
# Should be `JavaScript`
|
||||||
|
\bJavascript\b
|
||||||
|
|
||||||
|
# Should be `macOS` or `Mac OS X` or ...
|
||||||
|
\bMacOS\b
|
||||||
|
|
||||||
|
# Should be `Microsoft`
|
||||||
|
\bMicroSoft\b
|
||||||
|
|
||||||
|
# Should be `OAuth`
|
||||||
|
(?:^|[^-/*$])[ '"]oAuth(?: [a-z]|\d+ |[^ a-zA-Z0-9:;_.()])
|
||||||
|
|
||||||
|
# Should be `RabbitMQ`
|
||||||
|
\bRabbitmq\b
|
||||||
|
|
||||||
|
# Should be `TensorFlow`
|
||||||
|
\bTensorflow\b
|
||||||
|
|
||||||
|
# Should be `TypeScript`
|
||||||
|
\bTypescript\b
|
||||||
|
|
||||||
|
# Should be `another`
|
||||||
|
\ban[- ]other(?!-)\b
|
||||||
|
|
||||||
|
# Should be `case-(in)sensitive`
|
||||||
|
\bcase (?:in|)sensitive\b
|
||||||
|
|
||||||
|
# Should be `coinciding`
|
||||||
|
\bco-inciding\b
|
||||||
|
|
||||||
|
# Should be `deprecation warning(s)`
|
||||||
|
\b[Dd]epreciation [Ww]arnings?\b
|
||||||
|
|
||||||
|
# Should be `greater than`
|
||||||
|
\bgreater then\b
|
||||||
|
|
||||||
|
# Should be `has`
|
||||||
|
\b[Ii]t only have\b
|
||||||
|
|
||||||
|
# Should be `here-in`, `the`, `them`, `this`, `these` or reworded in some other way
|
||||||
|
\bthe here(?:\.|,| (?!and|defined))
|
||||||
|
|
||||||
|
# Should be `greater than`
|
||||||
|
\bhigher than\b
|
||||||
|
|
||||||
|
# Should be `ID` (unless it's a flag/property)
|
||||||
|
(?<![-\.])\bId\b(?![(])
|
||||||
|
|
||||||
|
# Should be `in front of`
|
||||||
|
\bin from of\b
|
||||||
|
|
||||||
|
# Should be `into`
|
||||||
|
# when not phrasal and when `in order to` would be wrong:
|
||||||
|
# https://thewritepractice.com/into-vs-in-to/
|
||||||
|
\sin to\s(?!if\b)
|
||||||
|
|
||||||
|
# Should be `use`
|
||||||
|
\sin used by\b
|
||||||
|
|
||||||
|
# Should be `in-depth` if used as an adjective (but `in depth` when used as an adverb)
|
||||||
|
\bin depth\s(?!rather\b)\w{6,}
|
||||||
|
|
||||||
|
# Should be `in-flight` or `on the fly` (unless actually talking about airline flights)
|
||||||
|
\bon[- ]flight\b(?!=\s+(?:(?:\w{2}|)\d+|availability|booking|computer|data|delay|departure|management|performance|radar|reservation|scheduling|software|status|ticket|time|type|.*(?:hotel|taxi)))
|
||||||
|
|
||||||
|
# Should be `is obsolete`
|
||||||
|
\bis obsolescent\b
|
||||||
|
|
||||||
|
# Should be `it's` or `its`
|
||||||
|
\bits['’]
|
||||||
|
|
||||||
|
# Should be `its`
|
||||||
|
\bit's(?= own\b)
|
||||||
|
|
||||||
|
# Should be `its`
|
||||||
|
\bit's(?= only purpose\b)
|
||||||
|
|
||||||
|
# Should be `for its` (possessive) or `because it is`
|
||||||
|
\bfor it(?:'s| is)\b
|
||||||
|
|
||||||
|
# Should be `log in`
|
||||||
|
\blogin to the
|
||||||
|
|
||||||
|
# Should be `long-standing`
|
||||||
|
\blong standing\b
|
||||||
|
|
||||||
|
# `apt-key` is deprecated
|
||||||
|
# ... instead you should be writing a pair of files:
|
||||||
|
# ... * the gpg key added to a distinct key ring file based on your project/distro/key...
|
||||||
|
# ... * the sources.list in a district file -- not simply appended to `/etc/apt/sources.list` -- (there is a newer format [DEB822](https://manpages.debian.org/bookworm/dpkg-dev/deb822.5.en.html)) that references the gpg key.
|
||||||
|
# Consider:
|
||||||
|
# ````sh
|
||||||
|
# curl http://download.something.example.com/$DISTRO/Release.key | \
|
||||||
|
# gpg --dearmor --yes --output /usr/share/keyrings/something-distro.gpg
|
||||||
|
# echo "deb [signed-by=/usr/share/keyrings/something-distro.gpg] http://download.something.example.com/repositories/home:/$DISTRO ./" \
|
||||||
|
# >> /etc/apt/sources.list.d/something-distro.list
|
||||||
|
# ````
|
||||||
|
\bapt-key add\b
|
||||||
|
|
||||||
|
# Should be `nearby`
|
||||||
|
\bnear by\b
|
||||||
|
|
||||||
|
# Should probably be a person named `Nick` or the abbreviation `NIC`
|
||||||
|
\bNic\b
|
||||||
|
|
||||||
|
# Should be `not supposed`
|
||||||
|
\bsupposed not\b
|
||||||
|
|
||||||
|
# Should probably be `much more`
|
||||||
|
\bmore much\b
|
||||||
|
|
||||||
|
# Should be `perform its`
|
||||||
|
\bperform it's\b
|
||||||
|
|
||||||
|
# Should be `opt-in`
|
||||||
|
(?<!\scan|for)(?<!\smust)(?<!\sif)\sopt in\s
|
||||||
|
|
||||||
|
# Should be `less than`
|
||||||
|
\bless then\b
|
||||||
|
|
||||||
|
# Should be `load balancer`
|
||||||
|
\b[Ll]oud balancer
|
||||||
|
|
||||||
|
# Should be `moot`
|
||||||
|
\bmute point\b
|
||||||
|
|
||||||
|
# Should be `one of`
|
||||||
|
(?<!-)\bon of\b
|
||||||
|
|
||||||
|
# Should be `on the other hand`
|
||||||
|
\b(?i)on another hand\b
|
||||||
|
|
||||||
|
# Reword to `on at runtime` or `enabled at launch`
|
||||||
|
# The former if you mean it can be changed dynamically.
|
||||||
|
# The latter if you mean that it can be changed without recompiling but not after the program starts.
|
||||||
|
\bswitched on runtime\b
|
||||||
|
|
||||||
|
# Should be `Of course,`
|
||||||
|
[?.!]\s+Of course\s(?=[-\w\s]+[.?;!,])
|
||||||
|
|
||||||
|
# Most people only have two hands. Reword.
|
||||||
|
\b(?i)on the third hand\b
|
||||||
|
|
||||||
|
# Should be `Open Graph`
|
||||||
|
# unless talking about a specific Open Graph implementation:
|
||||||
|
# - Java
|
||||||
|
# - Node
|
||||||
|
# - Py
|
||||||
|
# - Ruby
|
||||||
|
\bOpenGraph\b
|
||||||
|
|
||||||
|
# Should be `OpenShift`
|
||||||
|
\bOpenshift\b
|
||||||
|
|
||||||
|
# Should be `otherwise`
|
||||||
|
\bother[- ]wise\b
|
||||||
|
|
||||||
|
# Should be `; otherwise` or `. Otherwise`
|
||||||
|
# https://study.com/learn/lesson/otherwise-in-a-sentence.html
|
||||||
|
, [Oo]therwise\b
|
||||||
|
|
||||||
|
# Should probably be `Otherwise,`
|
||||||
|
(?<=\. )Otherwise\s
|
||||||
|
|
||||||
|
# Should be `or (more|less)`
|
||||||
|
\bore (?:more|less)\b
|
||||||
|
|
||||||
|
# Should be `rather than`
|
||||||
|
\brather then\b
|
||||||
|
|
||||||
|
# Should be `Red Hat`
|
||||||
|
\bRed[Hh]at\b
|
||||||
|
|
||||||
|
# Should be `regardless, ...` or `regardless of (whether)`
|
||||||
|
\b[Rr]egardless if you\b
|
||||||
|
|
||||||
|
# Should be `self-signed`
|
||||||
|
\bself signed\b
|
||||||
|
|
||||||
|
# Should be `SendGrid`
|
||||||
|
\bSendgrid\b
|
||||||
|
|
||||||
|
# Should be `set up` (`setup` is a noun / `set up` is a verb)
|
||||||
|
\b[Ss]etup(?= (?:an?|the)\b)
|
||||||
|
|
||||||
|
# Should be `state`
|
||||||
|
\bsate(?=\b|[A-Z])|(?<=[a-z])Sate(?=\b|[A-Z])|(?<=[A-Z]{2})Sate(?=\b|[A-Z])
|
||||||
|
|
||||||
|
# Should be `no longer needed`
|
||||||
|
\bno more needed\b(?! than\b)
|
||||||
|
|
||||||
|
# Should be `<see|look> below for the`
|
||||||
|
(?i)\bfind below the\b
|
||||||
|
|
||||||
|
# Should be `then any` unless there's a comparison before the `,`
|
||||||
|
, than any\b
|
||||||
|
|
||||||
|
# Should be `did not exist`
|
||||||
|
\bwere not existent\b
|
||||||
|
|
||||||
|
# Should be `nonexistent`
|
||||||
|
\bnon existing\b
|
||||||
|
|
||||||
|
# Should be `nonexistent`
|
||||||
|
\b[Nn]o[nt][- ]existent\b
|
||||||
|
|
||||||
|
# Should be `our`
|
||||||
|
\bspending out time\b
|
||||||
|
|
||||||
|
# Should be `@brief` / `@details` / `@param` / `@return` / `@retval`
|
||||||
|
(?:^\s*|(?:\*|//|/*)\s+`)[\\@](?:breif|(?:detail|detials)|(?:params(?!\.)|prama?)|ret(?:uns?)|retvl)\b
|
||||||
|
|
||||||
|
# Should be `more than` or `more, then`
|
||||||
|
\bmore then\b
|
||||||
|
|
||||||
|
# Should be `Pipeline`/`pipeline`
|
||||||
|
(?:(?<=\b|[A-Z])p|P)ipeLine(?:\b|(?=[A-Z]))
|
||||||
|
|
||||||
|
# Should be `preexisting`
|
||||||
|
[Pp]re[- ]existing
|
||||||
|
|
||||||
|
# Should be `preempt`
|
||||||
|
[Pp]re[- ]empt\b
|
||||||
|
|
||||||
|
# Should be `preemptively`
|
||||||
|
[Pp]re[- ]emptively
|
||||||
|
|
||||||
|
# Should be `prepopulate`
|
||||||
|
[Pp]re[- ]populate
|
||||||
|
|
||||||
|
# Should be `prerequisite`
|
||||||
|
[Pp]re[- ]requisite
|
||||||
|
|
||||||
|
# Should be `recently changed` or `recent changes`
|
||||||
|
[Rr]ecent changed
|
||||||
|
|
||||||
|
# Should be `reentrancy`
|
||||||
|
[Rr]e[- ]entrancy
|
||||||
|
|
||||||
|
# Should be `reentrant`
|
||||||
|
[Rr]e[- ]entrant
|
||||||
|
|
||||||
|
# Should be `room for`
|
||||||
|
\brooms for (?!lease|rent|sale)
|
||||||
|
|
||||||
|
# Should be `socioeconomic`
|
||||||
|
# https://dictionary.cambridge.org/us/dictionary/english/socioeconomic
|
||||||
|
socio-economic
|
||||||
|
|
||||||
|
# Should be `strong suit`
|
||||||
|
\b(?:my|his|her|their) strong suite\b
|
||||||
|
|
||||||
|
# Should probably be `temperatures` unless actually talking about thermal drafts (things birds may fly on)
|
||||||
|
\bthermals\b
|
||||||
|
|
||||||
|
# Should be `there are` or `they are` (or `they're`)
|
||||||
|
(?i)\btheir are\b
|
||||||
|
|
||||||
|
# Should be `understand`
|
||||||
|
\bunder stand\b
|
||||||
|
|
||||||
|
# Should be `URI` or `uri` unless it refers to a person named `Uri` (or a flag)
|
||||||
|
(?<![-\.])\bUri\b(?![(])
|
||||||
|
|
||||||
|
# Should be `it uses is`
|
||||||
|
/\bis uses is\b/
|
||||||
|
|
||||||
|
# Should be `uses it as`
|
||||||
|
(?:^|\. |and )uses is as (?!an?\b|follows|livestock|[^.]+\s+as\b)
|
||||||
|
|
||||||
|
# Should be `was`
|
||||||
|
\bhas been(?= removed in v?\d)
|
||||||
|
|
||||||
|
# Should be `where`
|
||||||
|
\bwere they are\b
|
||||||
|
|
||||||
|
# Should be `why`
|
||||||
|
, way(?= is [^.]*\?)
|
||||||
|
|
||||||
|
# should be `vCenter`
|
||||||
|
\bV[Cc]enter\b
|
||||||
|
|
||||||
|
# Should be `VM`
|
||||||
|
\bVm\b
|
||||||
|
|
||||||
|
# Should be `walkthrough(s)`
|
||||||
|
\bwalk-throughs?\b
|
||||||
|
|
||||||
|
# Should be `we'll`
|
||||||
|
\bwe 'll\b
|
||||||
|
|
||||||
|
# Should be `whereas`
|
||||||
|
\bwhere as\b
|
||||||
|
|
||||||
|
# Should be `WinGet`
|
||||||
|
\bWinget\b
|
||||||
|
|
||||||
|
# Should be `without` (unless `out` is a modifier of the next word)
|
||||||
|
\bwith out\b(?!-)
|
||||||
|
|
||||||
|
# Should be `work around`
|
||||||
|
\b[Ww]orkaround(?= an?\b)
|
||||||
|
|
||||||
|
# Should be `workarounds`
|
||||||
|
\bwork[- ]arounds\b
|
||||||
|
|
||||||
|
# Should be `workaround`
|
||||||
|
(?:(?:[Aa]|[Tt]he|ugly)\swork[- ]around\b|\swork[- ]around\s+for)
|
||||||
|
|
||||||
|
# Should be `worst`
|
||||||
|
(?i)worse-case
|
||||||
|
|
||||||
|
# Should be `you are not` or reworded
|
||||||
|
\byour not\b
|
||||||
|
|
||||||
|
# Should be `(coarse|fine)-grained`
|
||||||
|
\b(?:coarse|fine) grained\b
|
||||||
|
|
||||||
|
# Homoglyph (Cyrillic) should be `A`/`B`/`C`/`E`/`H`/`I`/`I`/`J`/`K`/`M`/`O`/`P`/`S`/`T`/`Y`
|
||||||
|
# It's possible that your content is intentionally mixing Cyrillic and Latin scripts, but if it isn't, you definitely want to correct this.
|
||||||
|
(?<=[A-Z]{2})[АВСЕНІӀЈКМОРЅТУ]|[АВСЕНІӀЈКМОРЅТУ](?=[A-Z]+(?:\b|[a-z]+)|[a-z]+(?:[^a-z]|$))
|
||||||
|
|
||||||
|
# Homoglyph (Cyrillic) should be `a`/`b`/`c`/`e`/`o`/`p`/`x`/`y`
|
||||||
|
# It's possible that your content is intentionally mixing Cyrillic and Latin scripts, but if it isn't, you definitely want to correct this.
|
||||||
|
[авсеорху](?=[A-Za-z]{2,})|(?<=[A-Za-z]{2})[авсеорху]|(?<=[A-Za-z])[авсеорху](?=[A-Za-z])
|
||||||
|
|
||||||
|
# Should be `neither/nor` -- or reword
|
||||||
|
(?!<do )\bnot\b([^.?!"/(](?!neither|,.*?,))+\bnor\b
|
||||||
|
|
||||||
|
# Should be `neither/nor` (plus rewording the beginning)
|
||||||
|
# This is probably a double negative...
|
||||||
|
\bnot\b[^.?!"/(]*\bneither\b[^.?!"/(]*\bnor\b
|
||||||
|
|
||||||
|
# In English, duplicated words are generally mistakes
|
||||||
|
# There are a few exceptions (e.g. "that that").
|
||||||
|
# If the highlighted doubled word pair is in:
|
||||||
|
# * code, write a pattern to mask it.
|
||||||
|
# * prose, have someone read the English before you dismiss this error.
|
||||||
|
\s([A-Z]{3,}|[A-Z][a-z]{2,}|[a-z]{3,})\s\g{-1}\s
|
||||||
130
.github/actions/spelling/patterns.txt
vendored
Normal file
130
.github/actions/spelling/patterns.txt
vendored
Normal file
@@ -0,0 +1,130 @@
|
|||||||
|
# See https://github.com/check-spelling/check-spelling/wiki/Configuration-Examples:-patterns
|
||||||
|
|
||||||
|
# Automatically suggested patterns
|
||||||
|
|
||||||
|
# hit-count: 198 file-count: 52
|
||||||
|
# https/http/file urls
|
||||||
|
(?:\b(?:https?|ftp|file)://)[-A-Za-z0-9+&@#/*%?=~_|!:,.;]+[-A-Za-z0-9+&@#/*%=~_|]
|
||||||
|
|
||||||
|
# hit-count: 22 file-count: 8
|
||||||
|
# GitHub actions
|
||||||
|
\buses:\s+[-\w.]+/[-\w./]+@[-\w.]+
|
||||||
|
|
||||||
|
# hit-count: 19 file-count: 5
|
||||||
|
# libraries
|
||||||
|
(?:\b|_)[Ll]ib(?:re(?=office)|era(?![lt])|)(?!ero|erty|rar(?:i(?:an|es)|y))(?=[a-z])
|
||||||
|
|
||||||
|
# hit-count: 17 file-count: 8
|
||||||
|
# version suffix <word>v#
|
||||||
|
(?:(?<=[A-Z]{2})V|(?<=[a-z]{2}|[A-Z]{2})v)\d+(?:\b|(?=[a-zA-Z_]))
|
||||||
|
|
||||||
|
# hit-count: 15 file-count: 7
|
||||||
|
# container images
|
||||||
|
image: [-\w./:@]+
|
||||||
|
|
||||||
|
# hit-count: 14 file-count: 9
|
||||||
|
# imports
|
||||||
|
^import\s+(?:(?:static|type)\s+|)(?:[\w.]|\{\s*\w*?(?:,\s*(?:\w*|\*))+\s*\})+
|
||||||
|
|
||||||
|
# hit-count: 11 file-count: 2
|
||||||
|
# hex digits including css/html color classes:
|
||||||
|
(?:[\\0][xX]|\\u|[uU]\+|#x?|%23|&H)[0-9_a-fA-FgGrR]*?[a-fA-FgGrR]{2,}[0-9_a-fA-FgGrR]*(?:[uUlL]{0,3}|[iu]\d+)\b
|
||||||
|
|
||||||
|
# hit-count: 8 file-count: 5
|
||||||
|
# node packages
|
||||||
|
(["'])@[^/'" ]+/[^/'" ]+\g{-1}
|
||||||
|
|
||||||
|
# hit-count: 5 file-count: 2
|
||||||
|
# css fonts
|
||||||
|
\bfont(?:-family|):[^;}]+
|
||||||
|
|
||||||
|
# hit-count: 4 file-count: 4
|
||||||
|
# set arguments
|
||||||
|
\b(?:bash|sh|set)(?:\s+[-+][abefimouxE]{1,2})*\s+[-+][abefimouxE]{3,}(?:\s+[-+][abefimouxE]+)*
|
||||||
|
|
||||||
|
# hit-count: 4 file-count: 2
|
||||||
|
# css url wrappings
|
||||||
|
\burl\([^)]+\)
|
||||||
|
|
||||||
|
# hit-count: 2 file-count: 2
|
||||||
|
# C network byte conversions
|
||||||
|
(?:\d|\bh)to(?!ken)(?=[a-z])|to(?=[adhiklpun]\()
|
||||||
|
|
||||||
|
# hit-count: 2 file-count: 1
|
||||||
|
# GitHub SHA refs
|
||||||
|
\[([0-9a-f]+)\]\(https://(?:www\.|)github.com/[-\w]+/[-\w]+/commit/\g{-1}[0-9a-f]*
|
||||||
|
|
||||||
|
# hit-count: 1 file-count: 1
|
||||||
|
# copyright
|
||||||
|
Copyright (?:\([Cc]\)|)(?:[-\d, ]|and)+(?: [A-Z][a-z]+ [A-Z][a-z]+,?)+
|
||||||
|
|
||||||
|
# hit-count: 1 file-count: 1
|
||||||
|
# IPv6
|
||||||
|
\b(?:[0-9a-fA-F]{0,4}:){3,7}[0-9a-fA-F]{0,4}\b
|
||||||
|
|
||||||
|
# hit-count: 1 file-count: 1
|
||||||
|
# Docker images
|
||||||
|
^\s*(?i)FROM\s+\S+:\S+(?:\s+AS\s+\S+|)
|
||||||
|
|
||||||
|
# hit-count: 1 file-count: 1
|
||||||
|
# perl run
|
||||||
|
perl(?:\s+-[a-zA-Z]\w*)+
|
||||||
|
|
||||||
|
# hit-count: 1 file-count: 1
|
||||||
|
# go install
|
||||||
|
go install(?:\s+[a-z]+\.[-@\w/.]+)+
|
||||||
|
|
||||||
|
# hit-count: 1 file-count: 1
|
||||||
|
# in check-spelling@v0.0.22+, printf markers aren't automatically consumed
|
||||||
|
# printf markers
|
||||||
|
(?<!\\)\\[nrt](?=[a-z]{2,})
|
||||||
|
|
||||||
|
# hit-count: 1 file-count: 1
|
||||||
|
# tar arguments
|
||||||
|
\b(?:\\n|)g?tar(?:\.exe|)(?:(?:\s+--[-a-zA-Z]+|\s+-[a-zA-Z]+|\s[ABGJMOPRSUWZacdfh-pr-xz]+\b)(?:=[^ ]*|))+
|
||||||
|
|
||||||
|
# Questionably acceptable forms of `in to`
|
||||||
|
# Personally, I prefer `log into`, but people object
|
||||||
|
# https://www.tprteaching.com/log-into-log-in-to-login/
|
||||||
|
\b(?:(?:[Ll]og(?:g(?=[a-z])|)|[Ss]ign)(?:ed|ing)?) in to\b
|
||||||
|
|
||||||
|
# to opt in
|
||||||
|
\bto opt in\b
|
||||||
|
|
||||||
|
# pass(ed|ing) in
|
||||||
|
\bpass(?:ed|ing) in\b
|
||||||
|
|
||||||
|
# acceptable duplicates
|
||||||
|
# ls directory listings
|
||||||
|
[-bcdlpsw](?:[-r][-w][-SsTtx]){3}[\.+*]?\s+\d+\s+\S+\s+\S+\s+[.\d]+(?:[KMGT]|)\s+
|
||||||
|
# mount
|
||||||
|
\bmount\s+-t\s+(\w+)\s+\g{-1}\b
|
||||||
|
# C types and repeated CSS values
|
||||||
|
\s(auto|buffalo|center|div|inherit|long|LONG|none|normal|solid|thin|transparent|very)(?: \g{-1})+\s
|
||||||
|
# C enum and struct
|
||||||
|
\b(?:enum|struct)\s+(\w+)\s+\g{-1}\b
|
||||||
|
# go templates
|
||||||
|
\s(\w+)\s+\g{-1}\s+\`(?:graphql|inject|json|yaml):
|
||||||
|
# doxygen / javadoc / .net
|
||||||
|
(?:[\\@](?:brief|defgroup|groupname|link|t?param|return|retval)|(?:public|private|\[Parameter(?:\(.+\)|)\])(?:\s+(?:static|override|readonly|required|virtual))*)(?:\s+\{\w+\}|)\s+(\w+)\s+\g{-1}\s
|
||||||
|
|
||||||
|
# macOS file path
|
||||||
|
(?:Contents\W+|(?!iOS)/)MacOS\b
|
||||||
|
|
||||||
|
# Python package registry has incorrect spelling for macOS / Mac OS X
|
||||||
|
"Operating System :: MacOS :: MacOS X"
|
||||||
|
|
||||||
|
# "company" in Germany
|
||||||
|
\bGmbH\b
|
||||||
|
|
||||||
|
# IntelliJ
|
||||||
|
\bIntelliJ\b
|
||||||
|
|
||||||
|
# Commit message -- Signed-off-by and friends
|
||||||
|
^\s*(?:(?:Based-on-patch|Co-authored|Helped|Mentored|Reported|Reviewed|Signed-off)-by|Thanks-to): (?:[^<]*<[^>]*>|[^<]*)\s*$
|
||||||
|
|
||||||
|
# Autogenerated revert commit message
|
||||||
|
^This reverts commit [0-9a-f]{40}\.$
|
||||||
|
|
||||||
|
# ignore long runs of a single character:
|
||||||
|
\b([A-Za-z])\g{-1}{3,}\b
|
||||||
23
.github/actions/spelling/reject.txt
vendored
Normal file
23
.github/actions/spelling/reject.txt
vendored
Normal file
@@ -0,0 +1,23 @@
|
|||||||
|
^attache$
|
||||||
|
^bellows?$
|
||||||
|
benefitting
|
||||||
|
occurences?
|
||||||
|
^dependan.*
|
||||||
|
^develope$
|
||||||
|
^developement$
|
||||||
|
^developpe
|
||||||
|
^Devers?$
|
||||||
|
^devex
|
||||||
|
^devide
|
||||||
|
^Devinn?[ae]
|
||||||
|
^devisal
|
||||||
|
^devisor
|
||||||
|
^diables?$
|
||||||
|
^oer$
|
||||||
|
Sorce
|
||||||
|
^[Ss]pae.*
|
||||||
|
^Teh$
|
||||||
|
^untill$
|
||||||
|
^untilling$
|
||||||
|
^venders?$
|
||||||
|
^wether.*
|
||||||
4
.github/workflows/docker-pr.yml
vendored
4
.github/workflows/docker-pr.yml
vendored
@@ -49,7 +49,7 @@ jobs:
|
|||||||
id: meta
|
id: meta
|
||||||
uses: docker/metadata-action@902fa8ec7d6ecbf8d84d538b9b233a880e428804 # v5.7.0
|
uses: docker/metadata-action@902fa8ec7d6ecbf8d84d538b9b233a880e428804 # v5.7.0
|
||||||
with:
|
with:
|
||||||
images: ghcr.io/techarohq/anubis
|
images: ghcr.io/${{ github.repository }}
|
||||||
|
|
||||||
- name: Build and push
|
- name: Build and push
|
||||||
id: build
|
id: build
|
||||||
@@ -58,7 +58,7 @@ jobs:
|
|||||||
npm run container
|
npm run container
|
||||||
env:
|
env:
|
||||||
PULL_REQUEST_ID: ${{ github.event.number }}
|
PULL_REQUEST_ID: ${{ github.event.number }}
|
||||||
DOCKER_REPO: ghcr.io/techarohq/anubis
|
DOCKER_REPO: ghcr.io/${{ github.repository }}
|
||||||
SLOG_LEVEL: debug
|
SLOG_LEVEL: debug
|
||||||
|
|
||||||
- run: |
|
- run: |
|
||||||
|
|||||||
13
.github/workflows/docker.yml
vendored
13
.github/workflows/docker.yml
vendored
@@ -27,6 +27,10 @@ jobs:
|
|||||||
fetch-depth: 0
|
fetch-depth: 0
|
||||||
persist-credentials: false
|
persist-credentials: false
|
||||||
|
|
||||||
|
- name: Set lowercase image name
|
||||||
|
run: |
|
||||||
|
echo "IMAGE=ghcr.io/${GITHUB_REPOSITORY,,}" >> $GITHUB_ENV
|
||||||
|
|
||||||
- name: Set up Homebrew
|
- name: Set up Homebrew
|
||||||
uses: Homebrew/actions/setup-homebrew@master
|
uses: Homebrew/actions/setup-homebrew@master
|
||||||
|
|
||||||
@@ -55,14 +59,14 @@ jobs:
|
|||||||
uses: docker/login-action@74a5d142397b4f367a81961eba4e8cd7edddf772 # v3.4.0
|
uses: docker/login-action@74a5d142397b4f367a81961eba4e8cd7edddf772 # v3.4.0
|
||||||
with:
|
with:
|
||||||
registry: ghcr.io
|
registry: ghcr.io
|
||||||
username: techarohq
|
username: ${{ github.repository_owner }}
|
||||||
password: ${{ secrets.GITHUB_TOKEN }}
|
password: ${{ secrets.GITHUB_TOKEN }}
|
||||||
|
|
||||||
- name: Docker meta
|
- name: Docker meta
|
||||||
id: meta
|
id: meta
|
||||||
uses: docker/metadata-action@902fa8ec7d6ecbf8d84d538b9b233a880e428804 # v5.7.0
|
uses: docker/metadata-action@902fa8ec7d6ecbf8d84d538b9b233a880e428804 # v5.7.0
|
||||||
with:
|
with:
|
||||||
images: ghcr.io/techarohq/anubis
|
images: ${{ env.IMAGE }}
|
||||||
|
|
||||||
- name: Build and push
|
- name: Build and push
|
||||||
id: build
|
id: build
|
||||||
@@ -70,12 +74,13 @@ jobs:
|
|||||||
npm ci
|
npm ci
|
||||||
npm run container
|
npm run container
|
||||||
env:
|
env:
|
||||||
DOCKER_REPO: ghcr.io/techarohq/anubis
|
DOCKER_REPO: ${{ env.IMAGE }}
|
||||||
SLOG_LEVEL: debug
|
SLOG_LEVEL: debug
|
||||||
|
|
||||||
|
|
||||||
- name: Generate artifact attestation
|
- name: Generate artifact attestation
|
||||||
uses: actions/attest-build-provenance@db473fddc028af60658334401dc6fa3ffd8669fd # v2.3.0
|
uses: actions/attest-build-provenance@db473fddc028af60658334401dc6fa3ffd8669fd # v2.3.0
|
||||||
with:
|
with:
|
||||||
subject-name: ghcr.io/techarohq/anubis
|
subject-name: ${{ env.IMAGE }}
|
||||||
subject-digest: ${{ steps.build.outputs.digest }}
|
subject-digest: ${{ steps.build.outputs.digest }}
|
||||||
push-to-registry: true
|
push-to-registry: true
|
||||||
|
|||||||
1
.github/workflows/docs-deploy.yml
vendored
1
.github/workflows/docs-deploy.yml
vendored
@@ -13,6 +13,7 @@ permissions:
|
|||||||
|
|
||||||
jobs:
|
jobs:
|
||||||
build:
|
build:
|
||||||
|
if: github.repository == 'TecharoHQ/anubis'
|
||||||
runs-on: ubuntu-24.04
|
runs-on: ubuntu-24.04
|
||||||
|
|
||||||
steps:
|
steps:
|
||||||
|
|||||||
2
.github/workflows/docs-test.yml
vendored
2
.github/workflows/docs-test.yml
vendored
@@ -24,7 +24,7 @@ jobs:
|
|||||||
id: meta
|
id: meta
|
||||||
uses: docker/metadata-action@902fa8ec7d6ecbf8d84d538b9b233a880e428804 # v5.7.0
|
uses: docker/metadata-action@902fa8ec7d6ecbf8d84d538b9b233a880e428804 # v5.7.0
|
||||||
with:
|
with:
|
||||||
images: ghcr.io/techarohq/anubis/docs
|
images: ghcr.io/${{ github.repository }}/docs
|
||||||
|
|
||||||
- name: Build and push
|
- name: Build and push
|
||||||
id: build
|
id: build
|
||||||
|
|||||||
5
.github/workflows/package-builds-stable.yml
vendored
5
.github/workflows/package-builds-stable.yml
vendored
@@ -64,10 +64,7 @@ jobs:
|
|||||||
|
|
||||||
- name: Build Packages
|
- name: Build Packages
|
||||||
run: |
|
run: |
|
||||||
wget https://github.com/TecharoHQ/yeet/releases/download/v0.2.2/yeet_0.2.2_amd64.deb -O var/yeet.deb
|
go tool yeet
|
||||||
sudo apt -y install -f ./var/yeet.deb
|
|
||||||
rm ./var/yeet.deb
|
|
||||||
yeet
|
|
||||||
|
|
||||||
- name: Upload released artifacts
|
- name: Upload released artifacts
|
||||||
env:
|
env:
|
||||||
|
|||||||
@@ -66,10 +66,7 @@ jobs:
|
|||||||
|
|
||||||
- name: Build Packages
|
- name: Build Packages
|
||||||
run: |
|
run: |
|
||||||
wget https://github.com/TecharoHQ/yeet/releases/download/v0.2.2/yeet_0.2.2_amd64.deb -O var/yeet.deb
|
go tool yeet
|
||||||
sudo apt -y install -f ./var/yeet.deb
|
|
||||||
rm ./var/yeet.deb
|
|
||||||
yeet
|
|
||||||
|
|
||||||
- uses: actions/upload-artifact@ea165f8d65b6e75b540449e92b4886f43607fa02 # v4.6.2
|
- uses: actions/upload-artifact@ea165f8d65b6e75b540449e92b4886f43607fa02 # v4.6.2
|
||||||
with:
|
with:
|
||||||
|
|||||||
118
.github/workflows/spelling.yml
vendored
Normal file
118
.github/workflows/spelling.yml
vendored
Normal file
@@ -0,0 +1,118 @@
|
|||||||
|
name: Check Spelling
|
||||||
|
|
||||||
|
# Comment management is handled through a secondary job, for details see:
|
||||||
|
# https://github.com/check-spelling/check-spelling/wiki/Feature%3A-Restricted-Permissions
|
||||||
|
#
|
||||||
|
# `jobs.comment-push` runs when a push is made to a repository and the `jobs.spelling` job needs to make a comment
|
||||||
|
# (in odd cases, it might actually run just to collapse a comment, but that's fairly rare)
|
||||||
|
# it needs `contents: write` in order to add a comment.
|
||||||
|
#
|
||||||
|
# `jobs.comment-pr` runs when a pull_request is made to a repository and the `jobs.spelling` job needs to make a comment
|
||||||
|
# or collapse a comment (in the case where it had previously made a comment and now no longer needs to show a comment)
|
||||||
|
# it needs `pull-requests: write` in order to manipulate those comments.
|
||||||
|
|
||||||
|
# Updating pull request branches is managed via comment handling.
|
||||||
|
# For details, see: https://github.com/check-spelling/check-spelling/wiki/Feature:-Update-expect-list
|
||||||
|
#
|
||||||
|
# These elements work together to make it happen:
|
||||||
|
#
|
||||||
|
# `on.issue_comment`
|
||||||
|
# This event listens to comments by users asking to update the metadata.
|
||||||
|
#
|
||||||
|
# `jobs.update`
|
||||||
|
# This job runs in response to an issue_comment and will push a new commit
|
||||||
|
# to update the spelling metadata.
|
||||||
|
#
|
||||||
|
# `with.experimental_apply_changes_via_bot`
|
||||||
|
# Tells the action to support and generate messages that enable it
|
||||||
|
# to make a commit to update the spelling metadata.
|
||||||
|
#
|
||||||
|
# `with.ssh_key`
|
||||||
|
# In order to trigger workflows when the commit is made, you can provide a
|
||||||
|
# secret (typically, a write-enabled github deploy key).
|
||||||
|
#
|
||||||
|
# For background, see: https://github.com/check-spelling/check-spelling/wiki/Feature:-Update-with-deploy-key
|
||||||
|
|
||||||
|
# SARIF reporting
|
||||||
|
#
|
||||||
|
# Access to SARIF reports is generally restricted (by GitHub) to members of the repository.
|
||||||
|
#
|
||||||
|
# Requires enabling `security-events: write`
|
||||||
|
# and configuring the action with `use_sarif: 1`
|
||||||
|
#
|
||||||
|
# For information on the feature, see: https://github.com/check-spelling/check-spelling/wiki/Feature:-SARIF-output
|
||||||
|
|
||||||
|
# Minimal workflow structure:
|
||||||
|
#
|
||||||
|
# on:
|
||||||
|
# push:
|
||||||
|
# ...
|
||||||
|
# pull_request_target:
|
||||||
|
# ...
|
||||||
|
# jobs:
|
||||||
|
# # you only want the spelling job, all others should be omitted
|
||||||
|
# spelling:
|
||||||
|
# # remove `security-events: write` and `use_sarif: 1`
|
||||||
|
# # remove `experimental_apply_changes_via_bot: 1`
|
||||||
|
# ... otherwise adjust the `with:` as you wish
|
||||||
|
|
||||||
|
on:
|
||||||
|
push:
|
||||||
|
branches:
|
||||||
|
- '**'
|
||||||
|
tags-ignore:
|
||||||
|
- '**'
|
||||||
|
pull_request:
|
||||||
|
branches:
|
||||||
|
- '**'
|
||||||
|
types:
|
||||||
|
- 'opened'
|
||||||
|
- 'reopened'
|
||||||
|
- 'synchronize'
|
||||||
|
|
||||||
|
jobs:
|
||||||
|
spelling:
|
||||||
|
name: Check Spelling
|
||||||
|
permissions:
|
||||||
|
contents: read
|
||||||
|
pull-requests: read
|
||||||
|
actions: read
|
||||||
|
security-events: write
|
||||||
|
outputs:
|
||||||
|
followup: ${{ steps.spelling.outputs.followup }}
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
if: ${{ contains(github.event_name, 'pull_request') || github.event_name == 'push' }}
|
||||||
|
concurrency:
|
||||||
|
group: spelling-${{ github.event.pull_request.number || github.ref }}
|
||||||
|
# note: If you use only_check_changed_files, you do not want cancel-in-progress
|
||||||
|
cancel-in-progress: true
|
||||||
|
steps:
|
||||||
|
- name: check-spelling
|
||||||
|
id: spelling
|
||||||
|
uses: check-spelling/check-spelling@67debf50669c7fc76fc8f5d7f996384535a72b77 # v0.0.24
|
||||||
|
with:
|
||||||
|
suppress_push_for_open_pull_request: ${{ github.actor != 'dependabot[bot]' && 1 }}
|
||||||
|
checkout: true
|
||||||
|
check_file_names: 1
|
||||||
|
post_comment: 0
|
||||||
|
use_magic_file: 1
|
||||||
|
warnings: bad-regex,binary-file,deprecated-feature,ignored-expect-variant,large-file,limited-references,no-newline-at-eof,noisy-file,non-alpha-in-dictionary,token-is-substring,unexpected-line-ending,whitespace-in-dictionary,minified-file,unsupported-configuration,no-files-to-check,unclosed-block-ignore-begin,unclosed-block-ignore-end
|
||||||
|
use_sarif: ${{ (!github.event.pull_request || (github.event.pull_request.head.repo.full_name == github.repository)) && 1 }}
|
||||||
|
check_extra_dictionaries: ""
|
||||||
|
dictionary_source_prefixes: >
|
||||||
|
{
|
||||||
|
"cspell": "https://raw.githubusercontent.com/check-spelling/cspell-dicts/v20241114/dictionaries/"
|
||||||
|
}
|
||||||
|
extra_dictionaries: |
|
||||||
|
cspell:software-terms/softwareTerms.txt
|
||||||
|
cspell:golang/go.txt
|
||||||
|
cspell:npm/npm.txt
|
||||||
|
cspell:k8s/k8s.txt
|
||||||
|
cspell:python/python/python-lib.txt
|
||||||
|
cspell:aws/aws.txt
|
||||||
|
cspell:node/node.txt
|
||||||
|
cspell:html/html.txt
|
||||||
|
cspell:filetypes/filetypes.txt
|
||||||
|
cspell:python/common/extra.txt
|
||||||
|
cspell:docker/docker-words.txt
|
||||||
|
cspell:fullstack/fullstack.txt
|
||||||
@@ -14,9 +14,10 @@
|
|||||||
|
|
||||||
Anubis is brought to you by sponsors and donors like:
|
Anubis is brought to you by sponsors and donors like:
|
||||||
|
|
||||||
[](https://distrust.co)
|
[](https://distrust.co?utm_campaign=github&utm_medium=referral&utm_content=anubis)
|
||||||
[](https://terminaltrove.com/?utm_campaign=github&utm_medium=referral&utm_content=anubis&utm_source=abgh)
|
[](https://terminaltrove.com/?utm_campaign=github&utm_medium=referral&utm_content=anubis&utm_source=abgh)
|
||||||
[](https://canine.tools)
|
[](https://canine.tools?utm_campaign=github&utm_medium=referral&utm_content=anubis)
|
||||||
|
[](https://weblate.org/?utm_campaign=github&utm_medium=referral&utm_content=anubis)
|
||||||
|
|
||||||
## Overview
|
## Overview
|
||||||
|
|
||||||
|
|||||||
@@ -11,7 +11,10 @@ var Version = "devel"
|
|||||||
|
|
||||||
// CookieName is the name of the cookie that Anubis uses in order to validate
|
// CookieName is the name of the cookie that Anubis uses in order to validate
|
||||||
// access.
|
// access.
|
||||||
const CookieName = "within.website-x-cmd-anubis-auth"
|
const CookieName = "techaro.lol-anubis-auth"
|
||||||
|
|
||||||
|
// WithDomainCookieName is the name that is prepended to the per-domain cookie used when COOKIE_DOMAIN is set.
|
||||||
|
const WithDomainCookieName = "techaro.lol-anubis-auth-for-"
|
||||||
|
|
||||||
// CookieDefaultExpirationTime is the amount of time before the cookie/JWT expires.
|
// CookieDefaultExpirationTime is the amount of time before the cookie/JWT expires.
|
||||||
const CookieDefaultExpirationTime = 7 * 24 * time.Hour
|
const CookieDefaultExpirationTime = 7 * 24 * time.Hour
|
||||||
|
|||||||
@@ -5,6 +5,7 @@ import (
|
|||||||
"context"
|
"context"
|
||||||
"crypto/ed25519"
|
"crypto/ed25519"
|
||||||
"crypto/rand"
|
"crypto/rand"
|
||||||
|
"crypto/tls"
|
||||||
"embed"
|
"embed"
|
||||||
"encoding/hex"
|
"encoding/hex"
|
||||||
"errors"
|
"errors"
|
||||||
@@ -55,6 +56,7 @@ var (
|
|||||||
redirectDomains = flag.String("redirect-domains", "", "list of domains separated by commas which anubis is allowed to redirect to. Leaving this unset allows any domain.")
|
redirectDomains = flag.String("redirect-domains", "", "list of domains separated by commas which anubis is allowed to redirect to. Leaving this unset allows any domain.")
|
||||||
slogLevel = flag.String("slog-level", "INFO", "logging level (see https://pkg.go.dev/log/slog#hdr-Levels)")
|
slogLevel = flag.String("slog-level", "INFO", "logging level (see https://pkg.go.dev/log/slog#hdr-Levels)")
|
||||||
target = flag.String("target", "http://localhost:3923", "target to reverse proxy to, set to an empty string to disable proxying when only using auth request")
|
target = flag.String("target", "http://localhost:3923", "target to reverse proxy to, set to an empty string to disable proxying when only using auth request")
|
||||||
|
targetInsecureSkipVerify = flag.Bool("target-insecure-skip-verify", false, "if true, skips TLS validation for the backend")
|
||||||
healthcheck = flag.Bool("healthcheck", false, "run a health check against Anubis")
|
healthcheck = flag.Bool("healthcheck", false, "run a health check against Anubis")
|
||||||
useRemoteAddress = flag.Bool("use-remote-address", false, "read the client's IP address from the network request, useful for debugging and running Anubis on bare metal")
|
useRemoteAddress = flag.Bool("use-remote-address", false, "read the client's IP address from the network request, useful for debugging and running Anubis on bare metal")
|
||||||
debugBenchmarkJS = flag.Bool("debug-benchmark-js", false, "respond to every request with a challenge for benchmarking hashrate")
|
debugBenchmarkJS = flag.Bool("debug-benchmark-js", false, "respond to every request with a challenge for benchmarking hashrate")
|
||||||
@@ -63,6 +65,7 @@ var (
|
|||||||
ogCacheConsiderHost = flag.Bool("og-cache-consider-host", false, "enable or disable the use of the host in the Open Graph tag cache")
|
ogCacheConsiderHost = flag.Bool("og-cache-consider-host", false, "enable or disable the use of the host in the Open Graph tag cache")
|
||||||
extractResources = flag.String("extract-resources", "", "if set, extract the static resources to the specified folder")
|
extractResources = flag.String("extract-resources", "", "if set, extract the static resources to the specified folder")
|
||||||
webmasterEmail = flag.String("webmaster-email", "", "if set, displays webmaster's email on the reject page for appeals")
|
webmasterEmail = flag.String("webmaster-email", "", "if set, displays webmaster's email on the reject page for appeals")
|
||||||
|
valkeyURL = flag.String("valkey-url", "", "Valkey URL for Anubis' state layer")
|
||||||
)
|
)
|
||||||
|
|
||||||
func keyFromHex(value string) (ed25519.PrivateKey, error) {
|
func keyFromHex(value string) (ed25519.PrivateKey, error) {
|
||||||
@@ -133,7 +136,7 @@ func setupListener(network string, address string) (net.Listener, string) {
|
|||||||
return listener, formattedAddress
|
return listener, formattedAddress
|
||||||
}
|
}
|
||||||
|
|
||||||
func makeReverseProxy(target string) (http.Handler, error) {
|
func makeReverseProxy(target string, insecureSkipVerify bool) (http.Handler, error) {
|
||||||
targetUri, err := url.Parse(target)
|
targetUri, err := url.Parse(target)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, fmt.Errorf("failed to parse target URL: %w", err)
|
return nil, fmt.Errorf("failed to parse target URL: %w", err)
|
||||||
@@ -155,6 +158,13 @@ func makeReverseProxy(target string) (http.Handler, error) {
|
|||||||
transport.RegisterProtocol("unix", libanubis.UnixRoundTripper{Transport: transport})
|
transport.RegisterProtocol("unix", libanubis.UnixRoundTripper{Transport: transport})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if insecureSkipVerify {
|
||||||
|
slog.Warn("TARGET_INSECURE_SKIP_VERIFY is set to true, TLS certificate validation will not be performed", "target", target)
|
||||||
|
transport.TLSClientConfig = &tls.Config{
|
||||||
|
InsecureSkipVerify: true,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
rp := httputil.NewSingleHostReverseProxy(targetUri)
|
rp := httputil.NewSingleHostReverseProxy(targetUri)
|
||||||
rp.Transport = transport
|
rp.Transport = transport
|
||||||
|
|
||||||
@@ -196,7 +206,7 @@ func main() {
|
|||||||
// when using anubis via Systemd and environment variables, then it is not possible to set targe to an empty string but only to space
|
// when using anubis via Systemd and environment variables, then it is not possible to set targe to an empty string but only to space
|
||||||
if strings.TrimSpace(*target) != "" {
|
if strings.TrimSpace(*target) != "" {
|
||||||
var err error
|
var err error
|
||||||
rp, err = makeReverseProxy(*target)
|
rp, err = makeReverseProxy(*target, *targetInsecureSkipVerify)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Fatalf("can't make reverse proxy: %v", err)
|
log.Fatalf("can't make reverse proxy: %v", err)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -48,7 +48,16 @@ bots:
|
|||||||
- name: generic-browser
|
- name: generic-browser
|
||||||
user_agent_regex: >-
|
user_agent_regex: >-
|
||||||
Mozilla|Opera
|
Mozilla|Opera
|
||||||
action: CHALLENGE
|
action: WEIGH
|
||||||
|
weight:
|
||||||
|
adjust: 5
|
||||||
|
|
||||||
|
- name: high-pass-rate
|
||||||
|
pass_rate:
|
||||||
|
rate: 0.8
|
||||||
|
action: WEIGH
|
||||||
|
weight:
|
||||||
|
adjust: -15
|
||||||
|
|
||||||
dnsbl: false
|
dnsbl: false
|
||||||
|
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
- name: deny-aggressive-brazilian-scrapers
|
- name: aggressive-brazilian-scrapers
|
||||||
action: DENY
|
action: WEIGH
|
||||||
expression:
|
expression:
|
||||||
any:
|
any:
|
||||||
# Internet Explorer should be out of support
|
# Internet Explorer should be out of support
|
||||||
@@ -18,11 +18,9 @@
|
|||||||
- userAgent.contains("Win 9x")
|
- userAgent.contains("Win 9x")
|
||||||
# Amazon does not have an Alexa Toolbar.
|
# Amazon does not have an Alexa Toolbar.
|
||||||
- userAgent.contains("Alexa Toolbar")
|
- userAgent.contains("Alexa Toolbar")
|
||||||
- name: challenge-aggressive-brazilian-scrapers
|
|
||||||
action: CHALLENGE
|
|
||||||
expression:
|
|
||||||
any:
|
|
||||||
# This is not released, even Windows 11 calls itself Windows 10
|
# This is not released, even Windows 11 calls itself Windows 10
|
||||||
- userAgent.contains("Windows NT 11.0")
|
- userAgent.contains("Windows NT 11.0")
|
||||||
# iPods are not in common use
|
# iPods are not in common use
|
||||||
- userAgent.contains("iPod")
|
- userAgent.contains("iPod")
|
||||||
|
weight:
|
||||||
|
adjust: 10
|
||||||
@@ -1,4 +1,6 @@
|
|||||||
- name: cloudflare-workers
|
- name: cloudflare-workers
|
||||||
headers_regex:
|
headers_regex:
|
||||||
CF-Worker: .*
|
CF-Worker: .*
|
||||||
action: DENY
|
action: WEIGH
|
||||||
|
weight:
|
||||||
|
adjust: 5
|
||||||
@@ -1,9 +1,14 @@
|
|||||||
- name: lightpanda
|
- name: lightpanda
|
||||||
user_agent_regex: ^LightPanda/.*$
|
user_agent_regex: ^LightPanda/.*$
|
||||||
action: DENY
|
action: WEIGH
|
||||||
|
weight:
|
||||||
|
adjust: 5
|
||||||
- name: headless-chrome
|
- name: headless-chrome
|
||||||
user_agent_regex: HeadlessChrome
|
user_agent_regex: HeadlessChrome
|
||||||
action: DENY
|
action: WEIGH
|
||||||
|
weight:
|
||||||
|
adjust: 5
|
||||||
- name: headless-chromium
|
- name: headless-chromium
|
||||||
user_agent_regex: HeadlessChromium
|
user_agent_regex: HeadlessChromium
|
||||||
action: DENY
|
weight:
|
||||||
|
adjust: 5
|
||||||
@@ -3,7 +3,7 @@
|
|||||||
action: ALLOW
|
action: ALLOW
|
||||||
expression:
|
expression:
|
||||||
all:
|
all:
|
||||||
- remoteAddress == "159.69.213.214"
|
- remoteAddress == "159.69.213.214" || remoteAddress == "2a01:4f8:c2c:7bf4::1"
|
||||||
- userAgent == "Mozilla/5.0 (compatible; utils.web Limnoria module)"
|
- userAgent == "Mozilla/5.0 (compatible; utils.web Limnoria module)"
|
||||||
- '"X-Http-Version" in headers'
|
- '"X-Http-Version" in headers'
|
||||||
- headers["X-Http-Version"] == "HTTP/1.1"
|
- headers["X-Http-Version"] == "HTTP/1.1"
|
||||||
@@ -1,3 +1,5 @@
|
|||||||
- name: no-user-agent-string
|
- name: no-user-agent-string
|
||||||
action: DENY
|
action: WEIGH
|
||||||
expression: userAgent == ""
|
expression: userAgent == ""
|
||||||
|
weight:
|
||||||
|
adjust: 10
|
||||||
@@ -11,6 +11,14 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
|
|||||||
|
|
||||||
## [Unreleased]
|
## [Unreleased]
|
||||||
|
|
||||||
|
- Add `check-spelling` for spell checking
|
||||||
|
- Add `--target-insecure-skip-verify` flag/envvar to allow Anubis to hit a self-signed HTTPS backend
|
||||||
|
- Minor adjustments to FreeBSD rc.d script to allow for more flexible configuration.
|
||||||
|
- Added Podman and Docker support for running Playwright tests
|
||||||
|
- Updated the nonce value in the challenge JWT cookie to be a string instead of a number
|
||||||
|
- Rename cookies in response to user feedback
|
||||||
|
- Ensure cookie renaming is consistent across configuration options
|
||||||
|
|
||||||
## v1.18.0: Varis zos Galvus
|
## v1.18.0: Varis zos Galvus
|
||||||
|
|
||||||
The big ticket feature in this release is [CEL expression matching support](https://anubis.techaro.lol/docs/admin/configuration/expressions). This allows you to tailor your approach for the individual services you are protecting.
|
The big ticket feature in this release is [CEL expression matching support](https://anubis.techaro.lol/docs/admin/configuration/expressions). This allows you to tailor your approach for the individual services you are protecting.
|
||||||
@@ -65,7 +73,7 @@ Other changes:
|
|||||||
- Use CSS variables to deduplicate styles
|
- Use CSS variables to deduplicate styles
|
||||||
- Fixed native packages not containing the stdlib and botPolicies.yaml
|
- Fixed native packages not containing the stdlib and botPolicies.yaml
|
||||||
- Change import syntax to allow multi-level imports
|
- Change import syntax to allow multi-level imports
|
||||||
- Changed the startup logging to use JSON formatting as all the other logs do.
|
- Changed the startup logging to use JSON formatting as all the other logs do
|
||||||
- Added the ability to do [expression matching with CEL](./admin/configuration/expressions.mdx)
|
- Added the ability to do [expression matching with CEL](./admin/configuration/expressions.mdx)
|
||||||
- Add a warning for clients that don't store cookies
|
- Add a warning for clients that don't store cookies
|
||||||
- Disable Open Graph passthrough by default ([#435](https://github.com/TecharoHQ/anubis/issues/435))
|
- Disable Open Graph passthrough by default ([#435](https://github.com/TecharoHQ/anubis/issues/435))
|
||||||
|
|||||||
@@ -73,6 +73,21 @@ Anubis uses these environment variables for configuration:
|
|||||||
| `USE_REMOTE_ADDRESS` | unset | If set to `true`, Anubis will take the client's IP from the network socket. For production deployments, it is expected that a reverse proxy is used in front of Anubis, which pass the IP using headers, instead. |
|
| `USE_REMOTE_ADDRESS` | unset | If set to `true`, Anubis will take the client's IP from the network socket. For production deployments, it is expected that a reverse proxy is used in front of Anubis, which pass the IP using headers, instead. |
|
||||||
| `WEBMASTER_EMAIL` | unset | If set, shows a contact email address when rendering error pages. This email address will be how users can get in contact with administrators. |
|
| `WEBMASTER_EMAIL` | unset | If set, shows a contact email address when rendering error pages. This email address will be how users can get in contact with administrators. |
|
||||||
|
|
||||||
|
<details>
|
||||||
|
<summary>Advanced configuration settings</summary>
|
||||||
|
|
||||||
|
:::note
|
||||||
|
|
||||||
|
If you don't know or understand what these settings mean, ignore them. These are intended to work around very specific issues.
|
||||||
|
|
||||||
|
:::
|
||||||
|
|
||||||
|
| Environment Variable | Default value | Explanation |
|
||||||
|
| :---------------------------- | :------------ | :-------------------------------------------------------------------------------------------------------------------------------------------------- |
|
||||||
|
| `TARGET_INSECURE_SKIP_VERIFY` | `false` | If `true`, skip TLS certificate validation for targets that listen over `https`. If your backend does not listen over `https`, ignore this setting. |
|
||||||
|
|
||||||
|
</details>
|
||||||
|
|
||||||
For more detailed information on configuring Open Graph tags, please refer to the [Open Graph Configuration](./configuration/open-graph.mdx) page.
|
For more detailed information on configuring Open Graph tags, please refer to the [Open Graph Configuration](./configuration/open-graph.mdx) page.
|
||||||
|
|
||||||
### Using Base Prefix
|
### Using Base Prefix
|
||||||
|
|||||||
@@ -19,9 +19,10 @@ title: Anubis
|
|||||||
|
|
||||||
Anubis is brought to you by sponsors and donors like:
|
Anubis is brought to you by sponsors and donors like:
|
||||||
|
|
||||||
[](https://distrust.co)
|
[](https://distrust.co?utm_campaign=github&utm_medium=referral&utm_content=anubis)
|
||||||
[](https://terminaltrove.com/?utm_campaign=github&utm_medium=referral&utm_content=anubis&utm_source=abgh)
|
[](https://terminaltrove.com/?utm_campaign=github&utm_medium=referral&utm_content=anubis&utm_source=abgh)
|
||||||
[](https://canine.tools)
|
[](https://canine.tools?utm_campaign=github&utm_medium=referral&utm_content=anubis)
|
||||||
|
[](https://weblate.org/?utm_campaign=github&utm_medium=referral&utm_content=anubis)
|
||||||
|
|
||||||
## Overview
|
## Overview
|
||||||
|
|
||||||
|
|||||||
@@ -31,6 +31,9 @@ This page contains a non-exhaustive list with all websites using Anubis.
|
|||||||
- https://codeberg.org/
|
- https://codeberg.org/
|
||||||
- https://www.cfaarchive.org/
|
- https://www.cfaarchive.org/
|
||||||
- https://gitlab.freedesktop.org/
|
- https://gitlab.freedesktop.org/
|
||||||
|
- https://bugzilla.proxmox.com
|
||||||
|
- https://hofstede.io/
|
||||||
|
- https://www.indiemag.fr/
|
||||||
- <details>
|
- <details>
|
||||||
<summary>FreeCAD</summary>
|
<summary>FreeCAD</summary>
|
||||||
- https://forum.freecad.org/
|
- https://forum.freecad.org/
|
||||||
|
|||||||
BIN
docs/static/img/sponsors/weblate-logo.webp
vendored
Normal file
BIN
docs/static/img/sponsors/weblate-logo.webp
vendored
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 2.0 KiB |
65
go.mod
65
go.mod
@@ -1,8 +1,6 @@
|
|||||||
module github.com/TecharoHQ/anubis
|
module github.com/TecharoHQ/anubis
|
||||||
|
|
||||||
go 1.24.0
|
go 1.24.2
|
||||||
|
|
||||||
toolchain go1.24.2
|
|
||||||
|
|
||||||
require (
|
require (
|
||||||
github.com/a-h/templ v0.3.865
|
github.com/a-h/templ v0.3.865
|
||||||
@@ -11,6 +9,7 @@ require (
|
|||||||
github.com/google/cel-go v0.25.0
|
github.com/google/cel-go v0.25.0
|
||||||
github.com/playwright-community/playwright-go v0.5200.0
|
github.com/playwright-community/playwright-go v0.5200.0
|
||||||
github.com/prometheus/client_golang v1.22.0
|
github.com/prometheus/client_golang v1.22.0
|
||||||
|
github.com/redis/go-redis/v9 v9.8.0
|
||||||
github.com/sebest/xff v0.0.0-20210106013422-671bd2870b3a
|
github.com/sebest/xff v0.0.0-20210106013422-671bd2870b3a
|
||||||
github.com/yl2chen/cidranger v1.0.2
|
github.com/yl2chen/cidranger v1.0.2
|
||||||
golang.org/x/net v0.40.0
|
golang.org/x/net v0.40.0
|
||||||
@@ -18,33 +17,81 @@ require (
|
|||||||
)
|
)
|
||||||
|
|
||||||
require (
|
require (
|
||||||
|
al.essio.dev/pkg/shellescape v1.6.0 // indirect
|
||||||
cel.dev/expr v0.23.1 // indirect
|
cel.dev/expr v0.23.1 // indirect
|
||||||
|
dario.cat/mergo v1.0.1 // indirect
|
||||||
|
github.com/AlekSi/pointer v1.2.0 // indirect
|
||||||
github.com/BurntSushi/toml v1.4.1-0.20240526193622-a339e1f7089c // indirect
|
github.com/BurntSushi/toml v1.4.1-0.20240526193622-a339e1f7089c // indirect
|
||||||
|
github.com/Masterminds/goutils v1.1.1 // indirect
|
||||||
|
github.com/Masterminds/semver/v3 v3.3.1 // indirect
|
||||||
|
github.com/Masterminds/sprig/v3 v3.3.0 // indirect
|
||||||
|
github.com/Microsoft/go-winio v0.6.2 // indirect
|
||||||
|
github.com/ProtonMail/go-crypto v1.1.6 // indirect
|
||||||
|
github.com/Songmu/gitconfig v0.2.0 // indirect
|
||||||
|
github.com/TecharoHQ/yeet v0.2.3 // indirect
|
||||||
github.com/a-h/parse v0.0.0-20250122154542-74294addb73e // indirect
|
github.com/a-h/parse v0.0.0-20250122154542-74294addb73e // indirect
|
||||||
github.com/andybalholm/brotli v1.1.0 // indirect
|
github.com/andybalholm/brotli v1.1.0 // indirect
|
||||||
github.com/antlr4-go/antlr/v4 v4.13.0 // indirect
|
github.com/antlr4-go/antlr/v4 v4.13.0 // indirect
|
||||||
github.com/beorn7/perks v1.0.1 // indirect
|
github.com/beorn7/perks v1.0.1 // indirect
|
||||||
|
github.com/blakesmith/ar v0.0.0-20190502131153-809d4375e1fb // indirect
|
||||||
|
github.com/cavaliergopher/cpio v1.0.1 // indirect
|
||||||
github.com/cenkalti/backoff/v4 v4.3.0 // indirect
|
github.com/cenkalti/backoff/v4 v4.3.0 // indirect
|
||||||
github.com/cespare/xxhash/v2 v2.3.0 // indirect
|
github.com/cespare/xxhash/v2 v2.3.0 // indirect
|
||||||
github.com/cli/browser v1.3.0 // indirect
|
github.com/cli/browser v1.3.0 // indirect
|
||||||
|
github.com/cli/go-gh v0.1.0 // indirect
|
||||||
|
github.com/cloudflare/circl v1.6.0 // indirect
|
||||||
|
github.com/cyphar/filepath-securejoin v0.4.1 // indirect
|
||||||
github.com/deckarep/golang-set/v2 v2.7.0 // indirect
|
github.com/deckarep/golang-set/v2 v2.7.0 // indirect
|
||||||
|
github.com/dgryski/go-rendezvous v0.0.0-20200823014737-9f7001d12a5f // indirect
|
||||||
|
github.com/dlclark/regexp2 v1.11.4 // indirect
|
||||||
|
github.com/dop251/goja v0.0.0-20250309171923-bcd7cc6bf64c // indirect
|
||||||
|
github.com/emirpasic/gods v1.18.1 // indirect
|
||||||
github.com/facebookgo/ensure v0.0.0-20160127193407-b4ab57deab51 // indirect
|
github.com/facebookgo/ensure v0.0.0-20160127193407-b4ab57deab51 // indirect
|
||||||
github.com/facebookgo/stack v0.0.0-20160209184415-751773369052 // indirect
|
github.com/facebookgo/stack v0.0.0-20160209184415-751773369052 // indirect
|
||||||
github.com/facebookgo/subset v0.0.0-20150612182917-8dac2c3c4870 // indirect
|
github.com/facebookgo/subset v0.0.0-20150612182917-8dac2c3c4870 // indirect
|
||||||
github.com/fatih/color v1.16.0 // indirect
|
github.com/fatih/color v1.17.0 // indirect
|
||||||
github.com/fsnotify/fsnotify v1.7.0 // indirect
|
github.com/fsnotify/fsnotify v1.8.0 // indirect
|
||||||
|
github.com/go-git/gcfg v1.5.1-0.20230307220236-3a3c6141e376 // indirect
|
||||||
|
github.com/go-git/go-billy/v5 v5.6.2 // indirect
|
||||||
|
github.com/go-git/go-git/v5 v5.14.0 // indirect
|
||||||
github.com/go-jose/go-jose/v3 v3.0.4 // indirect
|
github.com/go-jose/go-jose/v3 v3.0.4 // indirect
|
||||||
|
github.com/go-sourcemap/sourcemap v2.1.3+incompatible // indirect
|
||||||
github.com/go-stack/stack v1.8.1 // indirect
|
github.com/go-stack/stack v1.8.1 // indirect
|
||||||
github.com/kr/text v0.2.0 // indirect
|
github.com/gobwas/glob v0.2.3 // indirect
|
||||||
|
github.com/goccy/go-yaml v1.12.0 // indirect
|
||||||
|
github.com/golang/groupcache v0.0.0-20241129210726-2c02b8208cf8 // indirect
|
||||||
|
github.com/google/pprof v0.0.0-20230207041349-798e818bf904 // indirect
|
||||||
|
github.com/google/rpmpack v0.6.1-0.20240329070804-c2247cbb881a // indirect
|
||||||
|
github.com/google/uuid v1.6.0 // indirect
|
||||||
|
github.com/goreleaser/chglog v0.7.0 // indirect
|
||||||
|
github.com/goreleaser/fileglob v1.3.0 // indirect
|
||||||
|
github.com/goreleaser/nfpm/v2 v2.42.0 // indirect
|
||||||
|
github.com/huandu/xstrings v1.5.0 // indirect
|
||||||
|
github.com/jbenet/go-context v0.0.0-20150711004518-d14ea06fba99 // indirect
|
||||||
|
github.com/kevinburke/ssh_config v1.2.0 // indirect
|
||||||
|
github.com/klauspost/compress v1.18.0 // indirect
|
||||||
|
github.com/klauspost/pgzip v1.2.6 // indirect
|
||||||
github.com/mattn/go-colorable v0.1.13 // indirect
|
github.com/mattn/go-colorable v0.1.13 // indirect
|
||||||
github.com/mattn/go-isatty v0.0.20 // indirect
|
github.com/mattn/go-isatty v0.0.20 // indirect
|
||||||
|
github.com/mitchellh/copystructure v1.2.0 // indirect
|
||||||
|
github.com/mitchellh/reflectwalk v1.0.2 // indirect
|
||||||
github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822 // indirect
|
github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822 // indirect
|
||||||
github.com/natefinch/atomic v1.0.1 // indirect
|
github.com/natefinch/atomic v1.0.1 // indirect
|
||||||
|
github.com/pjbgf/sha1cd v0.3.2 // indirect
|
||||||
|
github.com/pkg/errors v0.9.1 // indirect
|
||||||
github.com/prometheus/client_model v0.6.1 // indirect
|
github.com/prometheus/client_model v0.6.1 // indirect
|
||||||
github.com/prometheus/common v0.62.0 // indirect
|
github.com/prometheus/common v0.62.0 // indirect
|
||||||
github.com/prometheus/procfs v0.15.1 // indirect
|
github.com/prometheus/procfs v0.15.1 // indirect
|
||||||
|
github.com/sergi/go-diff v1.3.2-0.20230802210424-5b0b94c5c0d3 // indirect
|
||||||
|
github.com/shopspring/decimal v1.4.0 // indirect
|
||||||
|
github.com/skeema/knownhosts v1.3.1 // indirect
|
||||||
|
github.com/spf13/cast v1.7.1 // indirect
|
||||||
github.com/stoewer/go-strcase v1.2.0 // indirect
|
github.com/stoewer/go-strcase v1.2.0 // indirect
|
||||||
golang.org/x/exp v0.0.0-20231110203233-9a3e6036ecaa // indirect
|
github.com/ulikunitz/xz v0.5.12 // indirect
|
||||||
|
github.com/xanzy/ssh-agent v0.3.3 // indirect
|
||||||
|
gitlab.com/digitalxero/go-conventional-commit v1.0.7 // indirect
|
||||||
|
golang.org/x/crypto v0.38.0 // indirect
|
||||||
|
golang.org/x/exp v0.0.0-20240719175910-8a7402abbf56 // indirect
|
||||||
golang.org/x/exp/typeparams v0.0.0-20231108232855-2478ac86f678 // indirect
|
golang.org/x/exp/typeparams v0.0.0-20231108232855-2478ac86f678 // indirect
|
||||||
golang.org/x/mod v0.24.0 // indirect
|
golang.org/x/mod v0.24.0 // indirect
|
||||||
golang.org/x/sync v0.14.0 // indirect
|
golang.org/x/sync v0.14.0 // indirect
|
||||||
@@ -53,15 +100,19 @@ require (
|
|||||||
golang.org/x/text v0.25.0 // indirect
|
golang.org/x/text v0.25.0 // indirect
|
||||||
golang.org/x/tools v0.32.0 // indirect
|
golang.org/x/tools v0.32.0 // indirect
|
||||||
golang.org/x/vuln v1.1.4 // indirect
|
golang.org/x/vuln v1.1.4 // indirect
|
||||||
|
golang.org/x/xerrors v0.0.0-20240716161551-93cc26a95ae9 // indirect
|
||||||
google.golang.org/genproto/googleapis/api v0.0.0-20240826202546-f6391c0de4c7 // indirect
|
google.golang.org/genproto/googleapis/api v0.0.0-20240826202546-f6391c0de4c7 // indirect
|
||||||
google.golang.org/genproto/googleapis/rpc v0.0.0-20240826202546-f6391c0de4c7 // indirect
|
google.golang.org/genproto/googleapis/rpc v0.0.0-20240826202546-f6391c0de4c7 // indirect
|
||||||
google.golang.org/protobuf v1.36.5 // indirect
|
google.golang.org/protobuf v1.36.5 // indirect
|
||||||
|
gopkg.in/warnings.v0 v0.1.2 // indirect
|
||||||
|
gopkg.in/yaml.v3 v3.0.1 // indirect
|
||||||
honnef.co/go/tools v0.6.1 // indirect
|
honnef.co/go/tools v0.6.1 // indirect
|
||||||
sigs.k8s.io/json v0.0.0-20241010143419-9aa6b5e7a4b3 // indirect
|
sigs.k8s.io/json v0.0.0-20241010143419-9aa6b5e7a4b3 // indirect
|
||||||
sigs.k8s.io/yaml v1.4.0 // indirect
|
sigs.k8s.io/yaml v1.4.0 // indirect
|
||||||
)
|
)
|
||||||
|
|
||||||
tool (
|
tool (
|
||||||
|
github.com/TecharoHQ/yeet/cmd/yeet
|
||||||
github.com/a-h/templ/cmd/templ
|
github.com/a-h/templ/cmd/templ
|
||||||
golang.org/x/tools/cmd/goimports
|
golang.org/x/tools/cmd/goimports
|
||||||
golang.org/x/tools/cmd/stringer
|
golang.org/x/tools/cmd/stringer
|
||||||
|
|||||||
234
go.sum
234
go.sum
@@ -1,29 +1,92 @@
|
|||||||
|
al.essio.dev/pkg/shellescape v1.6.0 h1:NxFcEqzFSEVCGN2yq7Huv/9hyCEGVa/TncnOOBBeXHA=
|
||||||
|
al.essio.dev/pkg/shellescape v1.6.0/go.mod h1:6sIqp7X2P6mThCQ7twERpZTuigpr6KbZWtls1U8I890=
|
||||||
cel.dev/expr v0.23.1 h1:K4KOtPCJQjVggkARsjG9RWXP6O4R73aHeJMa/dmCQQg=
|
cel.dev/expr v0.23.1 h1:K4KOtPCJQjVggkARsjG9RWXP6O4R73aHeJMa/dmCQQg=
|
||||||
cel.dev/expr v0.23.1/go.mod h1:hLPLo1W4QUmuYdA72RBX06QTs6MXw941piREPl3Yfiw=
|
cel.dev/expr v0.23.1/go.mod h1:hLPLo1W4QUmuYdA72RBX06QTs6MXw941piREPl3Yfiw=
|
||||||
|
dario.cat/mergo v1.0.1 h1:Ra4+bf83h2ztPIQYNP99R6m+Y7KfnARDfID+a+vLl4s=
|
||||||
|
dario.cat/mergo v1.0.1/go.mod h1:uNxQE+84aUszobStD9th8a29P2fMDhsBdgRYvZOxGmk=
|
||||||
|
github.com/AlekSi/pointer v1.2.0 h1:glcy/gc4h8HnG2Z3ZECSzZ1IX1x2JxRVuDzaJwQE0+w=
|
||||||
|
github.com/AlekSi/pointer v1.2.0/go.mod h1:gZGfd3dpW4vEc/UlyfKKi1roIqcCgwOIvb0tSNSBle0=
|
||||||
github.com/BurntSushi/toml v1.4.1-0.20240526193622-a339e1f7089c h1:pxW6RcqyfI9/kWtOwnv/G+AzdKuy2ZrqINhenH4HyNs=
|
github.com/BurntSushi/toml v1.4.1-0.20240526193622-a339e1f7089c h1:pxW6RcqyfI9/kWtOwnv/G+AzdKuy2ZrqINhenH4HyNs=
|
||||||
github.com/BurntSushi/toml v1.4.1-0.20240526193622-a339e1f7089c/go.mod h1:ukJfTF/6rtPPRCnwkur4qwRxa8vTRFBF0uk2lLoLwho=
|
github.com/BurntSushi/toml v1.4.1-0.20240526193622-a339e1f7089c/go.mod h1:ukJfTF/6rtPPRCnwkur4qwRxa8vTRFBF0uk2lLoLwho=
|
||||||
|
github.com/DataDog/zstd v1.5.5 h1:oWf5W7GtOLgp6bciQYDmhHHjdhYkALu6S/5Ni9ZgSvQ=
|
||||||
|
github.com/DataDog/zstd v1.5.5/go.mod h1:g4AWEaM3yOg3HYfnJ3YIawPnVdXJh9QME85blwSAmyw=
|
||||||
|
github.com/MakeNowJust/heredoc v1.0.0/go.mod h1:mG5amYoWBHf8vpLOuehzbGGw0EHxpZZ6lCpQ4fNJ8LE=
|
||||||
|
github.com/Masterminds/goutils v1.1.1 h1:5nUrii3FMTL5diU80unEVvNevw1nH4+ZV4DSLVJLSYI=
|
||||||
|
github.com/Masterminds/goutils v1.1.1/go.mod h1:8cTjp+g8YejhMuvIA5y2vz3BpJxksy863GQaJW2MFNU=
|
||||||
|
github.com/Masterminds/semver/v3 v3.3.1 h1:QtNSWtVZ3nBfk8mAOu/B6v7FMJ+NHTIgUPi7rj+4nv4=
|
||||||
|
github.com/Masterminds/semver/v3 v3.3.1/go.mod h1:4V+yj/TJE1HU9XfppCwVMZq3I84lprf4nC11bSS5beM=
|
||||||
|
github.com/Masterminds/sprig/v3 v3.3.0 h1:mQh0Yrg1XPo6vjYXgtf5OtijNAKJRNcTdOOGZe3tPhs=
|
||||||
|
github.com/Masterminds/sprig/v3 v3.3.0/go.mod h1:Zy1iXRYNqNLUolqCpL4uhk6SHUMAOSCzdgBfDb35Lz0=
|
||||||
|
github.com/Microsoft/go-winio v0.5.2/go.mod h1:WpS1mjBmmwHBEWmogvA2mj8546UReBk4v8QkMxJ6pZY=
|
||||||
|
github.com/Microsoft/go-winio v0.6.2 h1:F2VQgta7ecxGYO8k3ZZz3RS8fVIXVxONVUPlNERoyfY=
|
||||||
|
github.com/Microsoft/go-winio v0.6.2/go.mod h1:yd8OoFMLzJbo9gZq8j5qaps8bJ9aShtEA8Ipt1oGCvU=
|
||||||
|
github.com/ProtonMail/go-crypto v1.1.6 h1:ZcV+Ropw6Qn0AX9brlQLAUXfqLBc7Bl+f/DmNxpLfdw=
|
||||||
|
github.com/ProtonMail/go-crypto v1.1.6/go.mod h1:rA3QumHc/FZ8pAHreoekgiAbzpNsfQAosU5td4SnOrE=
|
||||||
|
github.com/ProtonMail/go-mime v0.0.0-20230322103455-7d82a3887f2f h1:tCbYj7/299ekTTXpdwKYF8eBlsYsDVoggDAuAjoK66k=
|
||||||
|
github.com/ProtonMail/go-mime v0.0.0-20230322103455-7d82a3887f2f/go.mod h1:gcr0kNtGBqin9zDW9GOHcVntrwnjrK+qdJ06mWYBybw=
|
||||||
|
github.com/ProtonMail/gopenpgp/v2 v2.7.1 h1:Awsg7MPc2gD3I7IFac2qE3Gdls0lZW8SzrFZ3k1oz0s=
|
||||||
|
github.com/ProtonMail/gopenpgp/v2 v2.7.1/go.mod h1:/BU5gfAVwqyd8EfC3Eu7zmuhwYQpKs+cGD8M//iiaxs=
|
||||||
|
github.com/Songmu/gitconfig v0.2.0 h1:pX2++u4KUq+K2k/ZCzGXLtkD3ceCqIdi0tDyb+IbSyo=
|
||||||
|
github.com/Songmu/gitconfig v0.2.0/go.mod h1:cB5bYJer+pl7W8g6RHFwL/0X6aJROVrYuHlvc7PT+hE=
|
||||||
|
github.com/TecharoHQ/yeet v0.2.3 h1:Pcsnq5HTnk4Xntlu/FNEidH7x55bIx+f5Mk1hpVIngs=
|
||||||
|
github.com/TecharoHQ/yeet v0.2.3/go.mod h1:avLiwxZpNY37A/o35XledvdmGnTkm3G7+Oskxca6Z7Y=
|
||||||
github.com/a-h/parse v0.0.0-20250122154542-74294addb73e h1:HjVbSQHy+dnlS6C3XajZ69NYAb5jbGNfHanvm1+iYlo=
|
github.com/a-h/parse v0.0.0-20250122154542-74294addb73e h1:HjVbSQHy+dnlS6C3XajZ69NYAb5jbGNfHanvm1+iYlo=
|
||||||
github.com/a-h/parse v0.0.0-20250122154542-74294addb73e/go.mod h1:3mnrkvGpurZ4ZrTDbYU84xhwXW2TjTKShSwjRi2ihfQ=
|
github.com/a-h/parse v0.0.0-20250122154542-74294addb73e/go.mod h1:3mnrkvGpurZ4ZrTDbYU84xhwXW2TjTKShSwjRi2ihfQ=
|
||||||
github.com/a-h/templ v0.3.865 h1:nYn5EWm9EiXaDgWcMQaKiKvrydqgxDUtT1+4zU2C43A=
|
github.com/a-h/templ v0.3.865 h1:nYn5EWm9EiXaDgWcMQaKiKvrydqgxDUtT1+4zU2C43A=
|
||||||
github.com/a-h/templ v0.3.865/go.mod h1:oLBbZVQ6//Q6zpvSMPTuBK0F3qOtBdFBcGRspcT+VNQ=
|
github.com/a-h/templ v0.3.865/go.mod h1:oLBbZVQ6//Q6zpvSMPTuBK0F3qOtBdFBcGRspcT+VNQ=
|
||||||
github.com/andybalholm/brotli v1.1.0 h1:eLKJA0d02Lf0mVpIDgYnqXcUn0GqVmEFny3VuID1U3M=
|
github.com/andybalholm/brotli v1.1.0 h1:eLKJA0d02Lf0mVpIDgYnqXcUn0GqVmEFny3VuID1U3M=
|
||||||
github.com/andybalholm/brotli v1.1.0/go.mod h1:sms7XGricyQI9K10gOSf56VKKWS4oLer58Q+mhRPtnY=
|
github.com/andybalholm/brotli v1.1.0/go.mod h1:sms7XGricyQI9K10gOSf56VKKWS4oLer58Q+mhRPtnY=
|
||||||
|
github.com/anmitsu/go-shlex v0.0.0-20200514113438-38f4b401e2be h1:9AeTilPcZAjCFIImctFaOjnTIavg87rW78vTPkQqLI8=
|
||||||
|
github.com/anmitsu/go-shlex v0.0.0-20200514113438-38f4b401e2be/go.mod h1:ySMOLuWl6zY27l47sB3qLNK6tF2fkHG55UZxx8oIVo4=
|
||||||
github.com/antlr4-go/antlr/v4 v4.13.0 h1:lxCg3LAv+EUK6t1i0y1V6/SLeUi0eKEKdhQAlS8TVTI=
|
github.com/antlr4-go/antlr/v4 v4.13.0 h1:lxCg3LAv+EUK6t1i0y1V6/SLeUi0eKEKdhQAlS8TVTI=
|
||||||
github.com/antlr4-go/antlr/v4 v4.13.0/go.mod h1:pfChB/xh/Unjila75QW7+VU4TSnWnnk9UTnmpPaOR2g=
|
github.com/antlr4-go/antlr/v4 v4.13.0/go.mod h1:pfChB/xh/Unjila75QW7+VU4TSnWnnk9UTnmpPaOR2g=
|
||||||
|
github.com/armon/go-socks5 v0.0.0-20160902184237-e75332964ef5 h1:0CwZNZbxp69SHPdPJAN/hZIm0C4OItdklCFmMRWYpio=
|
||||||
|
github.com/armon/go-socks5 v0.0.0-20160902184237-e75332964ef5/go.mod h1:wHh0iHkYZB8zMSxRWpUBQtwG5a7fFgvEO+odwuTv2gs=
|
||||||
github.com/beorn7/perks v1.0.1 h1:VlbKKnNfV8bJzeqoa4cOKqO6bYr3WgKZxO8Z16+hsOM=
|
github.com/beorn7/perks v1.0.1 h1:VlbKKnNfV8bJzeqoa4cOKqO6bYr3WgKZxO8Z16+hsOM=
|
||||||
github.com/beorn7/perks v1.0.1/go.mod h1:G2ZrVWU2WbWT9wwq4/hrbKbnv/1ERSJQ0ibhJ6rlkpw=
|
github.com/beorn7/perks v1.0.1/go.mod h1:G2ZrVWU2WbWT9wwq4/hrbKbnv/1ERSJQ0ibhJ6rlkpw=
|
||||||
|
github.com/blakesmith/ar v0.0.0-20190502131153-809d4375e1fb h1:m935MPodAbYS46DG4pJSv7WO+VECIWUQ7OJYSoTrMh4=
|
||||||
|
github.com/blakesmith/ar v0.0.0-20190502131153-809d4375e1fb/go.mod h1:PkYb9DJNAwrSvRx5DYA+gUcOIgTGVMNkfSCbZM8cWpI=
|
||||||
|
github.com/bsm/ginkgo/v2 v2.12.0 h1:Ny8MWAHyOepLGlLKYmXG4IEkioBysk6GpaRTLC8zwWs=
|
||||||
|
github.com/bsm/ginkgo/v2 v2.12.0/go.mod h1:SwYbGRRDovPVboqFv0tPTcG1sN61LM1Z4ARdbAV9g4c=
|
||||||
|
github.com/bsm/gomega v1.27.10 h1:yeMWxP2pV2fG3FgAODIY8EiRE3dy0aeFYt4l7wh6yKA=
|
||||||
|
github.com/bsm/gomega v1.27.10/go.mod h1:JyEr/xRbxbtgWNi8tIEVPUYZ5Dzef52k01W3YH0H+O0=
|
||||||
|
github.com/caarlos0/testfs v0.4.4 h1:3PHvzHi5Lt+g332CiShwS8ogTgS3HjrmzZxCm6JCDr8=
|
||||||
|
github.com/caarlos0/testfs v0.4.4/go.mod h1:bRN55zgG4XCUVVHZCeU+/Tz1Q6AxEJOEJTliBy+1DMk=
|
||||||
|
github.com/cavaliergopher/cpio v1.0.1 h1:KQFSeKmZhv0cr+kawA3a0xTQCU4QxXF1vhU7P7av2KM=
|
||||||
|
github.com/cavaliergopher/cpio v1.0.1/go.mod h1:pBdaqQjnvXxdS/6CvNDwIANIFSP0xRKI16PX4xejRQc=
|
||||||
|
github.com/cavaliergopher/rpm v1.3.0 h1:UHX46sasX8MesUXXQ+UbkFLUX4eUWTlEcX8jcnRBIgI=
|
||||||
|
github.com/cavaliergopher/rpm v1.3.0/go.mod h1:vEumo1vvtrHM1Ov86f6+k8j7zNKOxQfHDCAIcR/36ZI=
|
||||||
github.com/cenkalti/backoff/v4 v4.3.0 h1:MyRJ/UdXutAwSAT+s3wNd7MfTIcy71VQueUuFK343L8=
|
github.com/cenkalti/backoff/v4 v4.3.0 h1:MyRJ/UdXutAwSAT+s3wNd7MfTIcy71VQueUuFK343L8=
|
||||||
github.com/cenkalti/backoff/v4 v4.3.0/go.mod h1:Y3VNntkOUPxTVeUxJ/G5vcM//AlwfmyYozVcomhLiZE=
|
github.com/cenkalti/backoff/v4 v4.3.0/go.mod h1:Y3VNntkOUPxTVeUxJ/G5vcM//AlwfmyYozVcomhLiZE=
|
||||||
github.com/cespare/xxhash/v2 v2.3.0 h1:UL815xU9SqsFlibzuggzjXhog7bL6oX9BbNZnL2UFvs=
|
github.com/cespare/xxhash/v2 v2.3.0 h1:UL815xU9SqsFlibzuggzjXhog7bL6oX9BbNZnL2UFvs=
|
||||||
github.com/cespare/xxhash/v2 v2.3.0/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs=
|
github.com/cespare/xxhash/v2 v2.3.0/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs=
|
||||||
|
github.com/cli/browser v1.1.0/go.mod h1:HKMQAt9t12kov91Mn7RfZxyJQQgWgyS/3SZswlZ5iTI=
|
||||||
github.com/cli/browser v1.3.0 h1:LejqCrpWr+1pRqmEPDGnTZOjsMe7sehifLynZJuqJpo=
|
github.com/cli/browser v1.3.0 h1:LejqCrpWr+1pRqmEPDGnTZOjsMe7sehifLynZJuqJpo=
|
||||||
github.com/cli/browser v1.3.0/go.mod h1:HH8s+fOAxjhQoBUAsKuPCbqUuxZDhQ2/aD+SzsEfBTk=
|
github.com/cli/browser v1.3.0/go.mod h1:HH8s+fOAxjhQoBUAsKuPCbqUuxZDhQ2/aD+SzsEfBTk=
|
||||||
github.com/creack/pty v1.1.9/go.mod h1:oKZEueFk5CKHvIhNR5MUki03XCEU+Q6VDXinZuGJ33E=
|
github.com/cli/go-gh v0.1.0 h1:kMqFmC3ECBrV2UKzlOHjNOTTchExVc5tjNHtCqk/zYk=
|
||||||
|
github.com/cli/go-gh v0.1.0/go.mod h1:eTGWl99EMZ+3Iau5C6dHyGAJRRia65MtdBtuhWc+84o=
|
||||||
|
github.com/cli/safeexec v1.0.0/go.mod h1:Z/D4tTN8Vs5gXYHDCbaM1S/anmEDnJb1iW0+EJ5zx3Q=
|
||||||
|
github.com/cli/shurcooL-graphql v0.0.1/go.mod h1:U7gCSuMZP/Qy7kbqkk5PrqXEeDgtfG5K+W+u8weorps=
|
||||||
|
github.com/cloudflare/circl v1.6.0 h1:cr5JKic4HI+LkINy2lg3W2jF8sHCVTBncJr5gIIq7qk=
|
||||||
|
github.com/cloudflare/circl v1.6.0/go.mod h1:uddAzsPgqdMAYatqJ0lsjX1oECcQLIlRpzZh3pJrofs=
|
||||||
|
github.com/cyphar/filepath-securejoin v0.4.1 h1:JyxxyPEaktOD+GAnqIqTf9A8tHyAG22rowi7HkoSU1s=
|
||||||
|
github.com/cyphar/filepath-securejoin v0.4.1/go.mod h1:Sdj7gXlvMcPZsbhwhQ33GguGLDGQL7h7bg04C/+u9jI=
|
||||||
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
|
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
|
||||||
github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
|
|
||||||
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
|
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
|
||||||
|
github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc h1:U9qPSI2PIWSS1VwoXQT9A3Wy9MM3WgvqSxFWenqJduM=
|
||||||
|
github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
|
||||||
github.com/deckarep/golang-set/v2 v2.7.0 h1:gIloKvD7yH2oip4VLhsv3JyLLFnC0Y2mlusgcvJYW5k=
|
github.com/deckarep/golang-set/v2 v2.7.0 h1:gIloKvD7yH2oip4VLhsv3JyLLFnC0Y2mlusgcvJYW5k=
|
||||||
github.com/deckarep/golang-set/v2 v2.7.0/go.mod h1:VAky9rY/yGXJOLEDv3OMci+7wtDpOF4IN+y82NBOac4=
|
github.com/deckarep/golang-set/v2 v2.7.0/go.mod h1:VAky9rY/yGXJOLEDv3OMci+7wtDpOF4IN+y82NBOac4=
|
||||||
|
github.com/dgryski/go-rendezvous v0.0.0-20200823014737-9f7001d12a5f h1:lO4WD4F/rVNCu3HqELle0jiPLLBs70cWOduZpkS1E78=
|
||||||
|
github.com/dgryski/go-rendezvous v0.0.0-20200823014737-9f7001d12a5f/go.mod h1:cuUVRXasLTGF7a8hSLbxyZXjz+1KgoB3wDUb6vlszIc=
|
||||||
|
github.com/dlclark/regexp2 v1.11.4 h1:rPYF9/LECdNymJufQKmri9gV604RvvABwgOA8un7yAo=
|
||||||
|
github.com/dlclark/regexp2 v1.11.4/go.mod h1:DHkYz0B9wPfa6wondMfaivmHpzrQ3v9q8cnmRbL6yW8=
|
||||||
|
github.com/dop251/goja v0.0.0-20250309171923-bcd7cc6bf64c h1:mxWGS0YyquJ/ikZOjSrRjjFIbUqIP9ojyYQ+QZTU3Rg=
|
||||||
|
github.com/dop251/goja v0.0.0-20250309171923-bcd7cc6bf64c/go.mod h1:MxLav0peU43GgvwVgNbLAj1s/bSGboKkhuULvq/7hx4=
|
||||||
|
github.com/elazarl/goproxy v1.7.2 h1:Y2o6urb7Eule09PjlhQRGNsqRfPmYI3KKQLFpCAV3+o=
|
||||||
|
github.com/elazarl/goproxy v1.7.2/go.mod h1:82vkLNir0ALaW14Rc399OTTjyNREgmdL2cVoIbS6XaE=
|
||||||
|
github.com/emirpasic/gods v1.18.1 h1:FXtiHYKDGKCW2KzwZKx0iC0PQmdlorYgdFG9jPXJ1Bc=
|
||||||
|
github.com/emirpasic/gods v1.18.1/go.mod h1:8tpGGwCnJ5H4r6BWwaV6OrWmMoPhUl5jm/FMNAnJvWQ=
|
||||||
github.com/facebookgo/ensure v0.0.0-20160127193407-b4ab57deab51 h1:0JZ+dUmQeA8IIVUMzysrX4/AKuQwWhV2dYQuPZdvdSQ=
|
github.com/facebookgo/ensure v0.0.0-20160127193407-b4ab57deab51 h1:0JZ+dUmQeA8IIVUMzysrX4/AKuQwWhV2dYQuPZdvdSQ=
|
||||||
github.com/facebookgo/ensure v0.0.0-20160127193407-b4ab57deab51/go.mod h1:Yg+htXGokKKdzcwhuNDwVvN+uBxDGXJ7G/VN1d8fa64=
|
github.com/facebookgo/ensure v0.0.0-20160127193407-b4ab57deab51/go.mod h1:Yg+htXGokKKdzcwhuNDwVvN+uBxDGXJ7G/VN1d8fa64=
|
||||||
github.com/facebookgo/flagenv v0.0.0-20160425205200-fcd59fca7456 h1:CkmB2l68uhvRlwOTPrwnuitSxi/S3Cg4L5QYOcL9MBc=
|
github.com/facebookgo/flagenv v0.0.0-20160425205200-fcd59fca7456 h1:CkmB2l68uhvRlwOTPrwnuitSxi/S3Cg4L5QYOcL9MBc=
|
||||||
@@ -32,16 +95,47 @@ github.com/facebookgo/stack v0.0.0-20160209184415-751773369052 h1:JWuenKqqX8nojt
|
|||||||
github.com/facebookgo/stack v0.0.0-20160209184415-751773369052/go.mod h1:UbMTZqLaRiH3MsBH8va0n7s1pQYcu3uTb8G4tygF4Zg=
|
github.com/facebookgo/stack v0.0.0-20160209184415-751773369052/go.mod h1:UbMTZqLaRiH3MsBH8va0n7s1pQYcu3uTb8G4tygF4Zg=
|
||||||
github.com/facebookgo/subset v0.0.0-20150612182917-8dac2c3c4870 h1:E2s37DuLxFhQDg5gKsWoLBOB0n+ZW8s599zru8FJ2/Y=
|
github.com/facebookgo/subset v0.0.0-20150612182917-8dac2c3c4870 h1:E2s37DuLxFhQDg5gKsWoLBOB0n+ZW8s599zru8FJ2/Y=
|
||||||
github.com/facebookgo/subset v0.0.0-20150612182917-8dac2c3c4870/go.mod h1:5tD+neXqOorC30/tWg0LCSkrqj/AR6gu8yY8/fpw1q0=
|
github.com/facebookgo/subset v0.0.0-20150612182917-8dac2c3c4870/go.mod h1:5tD+neXqOorC30/tWg0LCSkrqj/AR6gu8yY8/fpw1q0=
|
||||||
github.com/fatih/color v1.16.0 h1:zmkK9Ngbjj+K0yRhTVONQh1p/HknKYSlNT+vZCzyokM=
|
github.com/fatih/color v1.10.0/go.mod h1:ELkj/draVOlAH/xkhN6mQ50Qd0MPOk5AAr3maGEBuJM=
|
||||||
github.com/fatih/color v1.16.0/go.mod h1:fL2Sau1YI5c0pdGEVCbKQbLXB6edEj1ZgiY4NijnWvE=
|
github.com/fatih/color v1.13.0/go.mod h1:kLAiJbzzSOZDVNGyDpeOxJ47H46qBXwg5ILebYFFOfk=
|
||||||
github.com/fsnotify/fsnotify v1.7.0 h1:8JEhPFa5W2WU7YfeZzPNqzMP6Lwt7L2715Ggo0nosvA=
|
github.com/fatih/color v1.17.0 h1:GlRw1BRJxkpqUCBKzKOw098ed57fEsKeNjpTe3cSjK4=
|
||||||
github.com/fsnotify/fsnotify v1.7.0/go.mod h1:40Bi/Hjc2AVfZrqy+aj+yEI+/bRxZnMJyTJwOpGvigM=
|
github.com/fatih/color v1.17.0/go.mod h1:YZ7TlrGPkiz6ku9fK3TLD/pl3CpsiFyu8N92HLgmosI=
|
||||||
|
github.com/frankban/quicktest v1.14.6 h1:7Xjx+VpznH+oBnejlPUj8oUpdxnVs4f8XU8WnHkI4W8=
|
||||||
|
github.com/frankban/quicktest v1.14.6/go.mod h1:4ptaffx2x8+WTWXmUCuVU6aPUX1/Mz7zb5vbUoiM6w0=
|
||||||
|
github.com/fsnotify/fsnotify v1.8.0 h1:dAwr6QBTBZIkG8roQaJjGof0pp0EeF+tNV7YBP3F/8M=
|
||||||
|
github.com/fsnotify/fsnotify v1.8.0/go.mod h1:8jBTzvmWwFyi3Pb8djgCCO5IBqzKJ/Jwo8TRcHyHii0=
|
||||||
|
github.com/gliderlabs/ssh v0.3.8 h1:a4YXD1V7xMF9g5nTkdfnja3Sxy1PVDCj1Zg4Wb8vY6c=
|
||||||
|
github.com/gliderlabs/ssh v0.3.8/go.mod h1:xYoytBv1sV0aL3CavoDuJIQNURXkkfPA/wxQ1pL1fAU=
|
||||||
|
github.com/go-git/gcfg v1.5.1-0.20230307220236-3a3c6141e376 h1:+zs/tPmkDkHx3U66DAb0lQFJrpS6731Oaa12ikc+DiI=
|
||||||
|
github.com/go-git/gcfg v1.5.1-0.20230307220236-3a3c6141e376/go.mod h1:an3vInlBmSxCcxctByoQdvwPiA7DTK7jaaFDBTtu0ic=
|
||||||
|
github.com/go-git/go-billy/v5 v5.6.2 h1:6Q86EsPXMa7c3YZ3aLAQsMA0VlWmy43r6FHqa/UNbRM=
|
||||||
|
github.com/go-git/go-billy/v5 v5.6.2/go.mod h1:rcFC2rAsp/erv7CMz9GczHcuD0D32fWzH+MJAU+jaUU=
|
||||||
|
github.com/go-git/go-git-fixtures/v4 v4.3.2-0.20231010084843-55a94097c399 h1:eMje31YglSBqCdIqdhKBW8lokaMrL3uTkpGYlE2OOT4=
|
||||||
|
github.com/go-git/go-git-fixtures/v4 v4.3.2-0.20231010084843-55a94097c399/go.mod h1:1OCfN199q1Jm3HZlxleg+Dw/mwps2Wbk9frAWm+4FII=
|
||||||
|
github.com/go-git/go-git/v5 v5.14.0 h1:/MD3lCrGjCen5WfEAzKg00MJJffKhC8gzS80ycmCi60=
|
||||||
|
github.com/go-git/go-git/v5 v5.14.0/go.mod h1:Z5Xhoia5PcWA3NF8vRLURn9E5FRhSl7dGj9ItW3Wk5k=
|
||||||
github.com/go-jose/go-jose/v3 v3.0.4 h1:Wp5HA7bLQcKnf6YYao/4kpRpVMp/yf6+pJKV8WFSaNY=
|
github.com/go-jose/go-jose/v3 v3.0.4 h1:Wp5HA7bLQcKnf6YYao/4kpRpVMp/yf6+pJKV8WFSaNY=
|
||||||
github.com/go-jose/go-jose/v3 v3.0.4/go.mod h1:5b+7YgP7ZICgJDBdfjZaIt+H/9L9T/YQrVfLAMboGkQ=
|
github.com/go-jose/go-jose/v3 v3.0.4/go.mod h1:5b+7YgP7ZICgJDBdfjZaIt+H/9L9T/YQrVfLAMboGkQ=
|
||||||
|
github.com/go-playground/assert/v2 v2.0.1/go.mod h1:VDjEfimB/XKnb+ZQfWdccd7VUvScMdVu0Titje2rxJ4=
|
||||||
|
github.com/go-playground/locales v0.13.0 h1:HyWk6mgj5qFqCT5fjGBuRArbVDfE4hi8+e8ceBS/t7Q=
|
||||||
|
github.com/go-playground/locales v0.13.0/go.mod h1:taPMhCMXrRLJO55olJkUXHZBHCxTMfnGwq/HNwmWNS8=
|
||||||
|
github.com/go-playground/universal-translator v0.17.0 h1:icxd5fm+REJzpZx7ZfpaD876Lmtgy7VtROAbHHXk8no=
|
||||||
|
github.com/go-playground/universal-translator v0.17.0/go.mod h1:UkSxE5sNxxRwHyU+Scu5vgOQjsIJAF8j9muTVoKLVtA=
|
||||||
|
github.com/go-playground/validator/v10 v10.4.1/go.mod h1:nlOn6nFhuKACm19sB/8EGNn9GlaMV7XkbRSipzJ0Ii4=
|
||||||
|
github.com/go-playground/validator/v10 v10.10.0 h1:I7mrTYv78z8k8VXa/qJlOlEXn/nBh+BF8dHX5nt/dr0=
|
||||||
|
github.com/go-playground/validator/v10 v10.10.0/go.mod h1:74x4gJWsvQexRdW8Pn3dXSGrTK4nAUsbPlLADvpJkos=
|
||||||
|
github.com/go-sourcemap/sourcemap v2.1.3+incompatible h1:W1iEw64niKVGogNgBN3ePyLFfuisuzeidWPMPWmECqU=
|
||||||
|
github.com/go-sourcemap/sourcemap v2.1.3+incompatible/go.mod h1:F8jJfvm2KbVjc5NqelyYJmf/v5J0dwNLS2mL4sNA1Jg=
|
||||||
github.com/go-stack/stack v1.8.1 h1:ntEHSVwIt7PNXNpgPmVfMrNhLtgjlmnZha2kOpuRiDw=
|
github.com/go-stack/stack v1.8.1 h1:ntEHSVwIt7PNXNpgPmVfMrNhLtgjlmnZha2kOpuRiDw=
|
||||||
github.com/go-stack/stack v1.8.1/go.mod h1:dcoOX6HbPZSZptuspn9bctJ+N/CnF5gGygcUP3XYfe4=
|
github.com/go-stack/stack v1.8.1/go.mod h1:dcoOX6HbPZSZptuspn9bctJ+N/CnF5gGygcUP3XYfe4=
|
||||||
|
github.com/gobwas/glob v0.2.3 h1:A4xDbljILXROh+kObIiy5kIaPYD8e96x1tgBhUI5J+Y=
|
||||||
|
github.com/gobwas/glob v0.2.3/go.mod h1:d3Ez4x06l9bZtSvzIay5+Yzi0fmZzPgnTbPcKjJAkT8=
|
||||||
|
github.com/goccy/go-yaml v1.9.5/go.mod h1:U/jl18uSupI5rdI2jmuCswEA2htH9eXfferR3KfscvA=
|
||||||
|
github.com/goccy/go-yaml v1.12.0 h1:/1WHjnMsI1dlIBQutrvSMGZRQufVO3asrHfTwfACoPM=
|
||||||
|
github.com/goccy/go-yaml v1.12.0/go.mod h1:wKnAMd44+9JAAnGQpWVEgBzGt3YuTaQ4uXoHvE4m7WU=
|
||||||
github.com/golang-jwt/jwt/v5 v5.2.2 h1:Rl4B7itRWVtYIHFrSNd7vhTiz9UpLdi6gZhZ3wEeDy8=
|
github.com/golang-jwt/jwt/v5 v5.2.2 h1:Rl4B7itRWVtYIHFrSNd7vhTiz9UpLdi6gZhZ3wEeDy8=
|
||||||
github.com/golang-jwt/jwt/v5 v5.2.2/go.mod h1:pqrtFR0X4osieyHYxtmOUWsAWrfe1Q5UVIyoH402zdk=
|
github.com/golang-jwt/jwt/v5 v5.2.2/go.mod h1:pqrtFR0X4osieyHYxtmOUWsAWrfe1Q5UVIyoH402zdk=
|
||||||
|
github.com/golang/groupcache v0.0.0-20241129210726-2c02b8208cf8 h1:f+oWsMOmNPc8JmEHVZIycC7hBoQxHH9pNKQORJNozsQ=
|
||||||
|
github.com/golang/groupcache v0.0.0-20241129210726-2c02b8208cf8/go.mod h1:wcDNUvekVysuuOpQKo3191zZyTpiI6se1N1ULghS0sw=
|
||||||
github.com/google/cel-go v0.25.0 h1:jsFw9Fhn+3y2kBbltZR4VEz5xKkcIFRPDnuEzAGv5GY=
|
github.com/google/cel-go v0.25.0 h1:jsFw9Fhn+3y2kBbltZR4VEz5xKkcIFRPDnuEzAGv5GY=
|
||||||
github.com/google/cel-go v0.25.0/go.mod h1:hjEb6r5SuOSlhCHmFoLzu8HGCERvIsDAbxDAyNU/MmI=
|
github.com/google/cel-go v0.25.0/go.mod h1:hjEb6r5SuOSlhCHmFoLzu8HGCERvIsDAbxDAyNU/MmI=
|
||||||
github.com/google/go-cmdtest v0.4.1-0.20220921163831-55ab3332a786 h1:rcv+Ippz6RAtvaGgKxc+8FQIpxHgsF+HBzPyYL2cyVU=
|
github.com/google/go-cmdtest v0.4.1-0.20220921163831-55ab3332a786 h1:rcv+Ippz6RAtvaGgKxc+8FQIpxHgsF+HBzPyYL2cyVU=
|
||||||
@@ -49,31 +143,85 @@ github.com/google/go-cmdtest v0.4.1-0.20220921163831-55ab3332a786/go.mod h1:apVn
|
|||||||
github.com/google/go-cmp v0.5.9/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY=
|
github.com/google/go-cmp v0.5.9/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY=
|
||||||
github.com/google/go-cmp v0.7.0 h1:wk8382ETsv4JYUZwIsn6YpYiWiBsYLSJiTsyBybVuN8=
|
github.com/google/go-cmp v0.7.0 h1:wk8382ETsv4JYUZwIsn6YpYiWiBsYLSJiTsyBybVuN8=
|
||||||
github.com/google/go-cmp v0.7.0/go.mod h1:pXiqmnSA92OHEEa9HXL2W4E7lf9JzCmGVUdgjX3N/iU=
|
github.com/google/go-cmp v0.7.0/go.mod h1:pXiqmnSA92OHEEa9HXL2W4E7lf9JzCmGVUdgjX3N/iU=
|
||||||
|
github.com/google/pprof v0.0.0-20230207041349-798e818bf904 h1:4/hN5RUoecvl+RmJRE2YxKWtnnQls6rQjjW5oV7qg2U=
|
||||||
|
github.com/google/pprof v0.0.0-20230207041349-798e818bf904/go.mod h1:uglQLonpP8qtYCYyzA+8c/9qtqgA3qsXGYqCPKARAFg=
|
||||||
github.com/google/renameio v0.1.0 h1:GOZbcHa3HfsPKPlmyPyN2KEohoMXOhdMbHrvbpl2QaA=
|
github.com/google/renameio v0.1.0 h1:GOZbcHa3HfsPKPlmyPyN2KEohoMXOhdMbHrvbpl2QaA=
|
||||||
github.com/google/renameio v0.1.0/go.mod h1:KWCgfxg9yswjAJkECMjeO8J8rahYeXnNhOm40UhjYkI=
|
github.com/google/renameio v0.1.0/go.mod h1:KWCgfxg9yswjAJkECMjeO8J8rahYeXnNhOm40UhjYkI=
|
||||||
|
github.com/google/rpmpack v0.6.1-0.20240329070804-c2247cbb881a h1:JJBdjSfqSy3mnDT0940ASQFghwcZ4y4cb6ttjAoXqwE=
|
||||||
|
github.com/google/rpmpack v0.6.1-0.20240329070804-c2247cbb881a/go.mod h1:uqVAUVQLq8UY2hCDfmJ/+rtO3aw7qyhc90rCVEabEfI=
|
||||||
|
github.com/google/shlex v0.0.0-20191202100458-e7afc7fbc510 h1:El6M4kTTCOh6aBiKaUGG7oYTSPP8MxqL4YI3kZKwcP4=
|
||||||
|
github.com/google/shlex v0.0.0-20191202100458-e7afc7fbc510/go.mod h1:pupxD2MaaD3pAXIBCelhxNneeOaAeabZDe5s4K6zSpQ=
|
||||||
|
github.com/google/uuid v1.6.0 h1:NIvaJDMOsjHA8n1jAhLSgzrAzy1Hgr+hNrb57e+94F0=
|
||||||
|
github.com/google/uuid v1.6.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
|
||||||
|
github.com/gopherjs/gopherjs v1.17.2 h1:fQnZVsXk8uxXIStYb0N4bGk7jeyTalG/wsZjQ25dO0g=
|
||||||
|
github.com/gopherjs/gopherjs v1.17.2/go.mod h1:pRRIvn/QzFLrKfvEz3qUuEhtE/zLCWfreZ6J5gM2i+k=
|
||||||
|
github.com/goreleaser/chglog v0.7.0 h1:/KzXWAeg4DrEz4r3OI6K2Yb8RAsVGeInCUfLWFXL9C0=
|
||||||
|
github.com/goreleaser/chglog v0.7.0/go.mod h1:2h/yyq9xvTUeM9tOoucBP+jri8Dj28splx+SjlYkklc=
|
||||||
|
github.com/goreleaser/fileglob v1.3.0 h1:/X6J7U8lbDpQtBvGcwwPS6OpzkNVlVEsFUVRx9+k+7I=
|
||||||
|
github.com/goreleaser/fileglob v1.3.0/go.mod h1:Jx6BoXv3mbYkEzwm9THo7xbr5egkAraxkGorbJb4RxU=
|
||||||
|
github.com/goreleaser/nfpm/v2 v2.42.0 h1:7BW4WQWyvZDrT0C7SyWop+J8rtqFyTB17Sb2/j/NxMI=
|
||||||
|
github.com/goreleaser/nfpm/v2 v2.42.0/go.mod h1:DtNL+nKpfB8sMFZp+X7Xu3W64atyZYtTnYe8O925/mg=
|
||||||
|
github.com/h2non/parth v0.0.0-20190131123155-b4df798d6542/go.mod h1:Ow0tF8D4Kplbc8s8sSb3V2oUCygFHVp8gC3Dn6U4MNI=
|
||||||
|
github.com/henvic/httpretty v0.0.6/go.mod h1:X38wLjWXHkXT7r2+uK8LjCMne9rsuNaBLJ+5cU2/Pmo=
|
||||||
|
github.com/huandu/xstrings v1.5.0 h1:2ag3IFq9ZDANvthTwTiqSSZLjDc+BedvHPAp5tJy2TI=
|
||||||
|
github.com/huandu/xstrings v1.5.0/go.mod h1:y5/lhBue+AyNmUVz9RLU9xbLR0o4KIIExikq4ovT0aE=
|
||||||
|
github.com/jbenet/go-context v0.0.0-20150711004518-d14ea06fba99 h1:BQSFePA1RWJOlocH6Fxy8MmwDt+yVQYULKfN0RoTN8A=
|
||||||
|
github.com/jbenet/go-context v0.0.0-20150711004518-d14ea06fba99/go.mod h1:1lJo3i6rXxKeerYnT8Nvf0QmHCRC1n8sfWVwXF2Frvo=
|
||||||
|
github.com/jtolds/gls v4.20.0+incompatible h1:xdiiI2gbIgH/gLH7ADydsJ1uDOEzR8yvV7C0MuV77Wo=
|
||||||
|
github.com/jtolds/gls v4.20.0+incompatible/go.mod h1:QJZ7F/aHp+rZTRtaJ1ow/lLfFfVYBRgL+9YlvaHOwJU=
|
||||||
|
github.com/kevinburke/ssh_config v1.2.0 h1:x584FjTGwHzMwvHx18PXxbBVzfnxogHaAReU4gf13a4=
|
||||||
|
github.com/kevinburke/ssh_config v1.2.0/go.mod h1:CT57kijsi8u/K/BOFA39wgDQJ9CxiF4nAY/ojJ6r6mM=
|
||||||
|
github.com/kjk/lzma v0.0.0-20161016003348-3fd93898850d h1:RnWZeH8N8KXfbwMTex/KKMYMj0FJRCF6tQubUuQ02GM=
|
||||||
|
github.com/kjk/lzma v0.0.0-20161016003348-3fd93898850d/go.mod h1:phT/jsRPBAEqjAibu1BurrabCBNTYiVI+zbmyCZJY6Q=
|
||||||
github.com/klauspost/compress v1.18.0 h1:c/Cqfb0r+Yi+JtIEq73FWXVkRonBlf0CRNYc8Zttxdo=
|
github.com/klauspost/compress v1.18.0 h1:c/Cqfb0r+Yi+JtIEq73FWXVkRonBlf0CRNYc8Zttxdo=
|
||||||
github.com/klauspost/compress v1.18.0/go.mod h1:2Pp+KzxcywXVXMr50+X0Q/Lsb43OQHYWRCY2AiWywWQ=
|
github.com/klauspost/compress v1.18.0/go.mod h1:2Pp+KzxcywXVXMr50+X0Q/Lsb43OQHYWRCY2AiWywWQ=
|
||||||
|
github.com/klauspost/pgzip v1.2.6 h1:8RXeL5crjEUFnR2/Sn6GJNWtSQ3Dk8pq4CL3jvdDyjU=
|
||||||
|
github.com/klauspost/pgzip v1.2.6/go.mod h1:Ch1tH69qFZu15pkjo5kYi6mth2Zzwzt50oCQKQE9RUs=
|
||||||
|
github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo=
|
||||||
github.com/kr/pretty v0.3.1 h1:flRD4NNwYAUpkphVc1HcthR4KEIFJ65n8Mw5qdRn3LE=
|
github.com/kr/pretty v0.3.1 h1:flRD4NNwYAUpkphVc1HcthR4KEIFJ65n8Mw5qdRn3LE=
|
||||||
github.com/kr/pretty v0.3.1/go.mod h1:hoEshYVHaxMs3cyo3Yncou5ZscifuDolrwPKZanG3xk=
|
github.com/kr/pretty v0.3.1/go.mod h1:hoEshYVHaxMs3cyo3Yncou5ZscifuDolrwPKZanG3xk=
|
||||||
|
github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ=
|
||||||
|
github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI=
|
||||||
github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY=
|
github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY=
|
||||||
github.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE=
|
github.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE=
|
||||||
github.com/kylelemons/godebug v1.1.0 h1:RPNrshWIDI6G2gRW9EHilWtl7Z6Sb1BR0xunSBf0SNc=
|
github.com/kylelemons/godebug v1.1.0 h1:RPNrshWIDI6G2gRW9EHilWtl7Z6Sb1BR0xunSBf0SNc=
|
||||||
github.com/kylelemons/godebug v1.1.0/go.mod h1:9/0rRGxNHcop5bhtWyNeEfOS8JIWk580+fNqagV/RAw=
|
github.com/kylelemons/godebug v1.1.0/go.mod h1:9/0rRGxNHcop5bhtWyNeEfOS8JIWk580+fNqagV/RAw=
|
||||||
|
github.com/leodido/go-urn v1.2.0 h1:hpXL4XnriNwQ/ABnpepYM/1vCLWNDfUNts8dX3xTG6Y=
|
||||||
|
github.com/leodido/go-urn v1.2.0/go.mod h1:+8+nEpDfqqsY+g338gtMEUOtuK+4dEMhiQEgxpxOKII=
|
||||||
|
github.com/matryer/is v1.4.0 h1:sosSmIWwkYITGrxZ25ULNDeKiMNzFSr4V/eqBQP0PeE=
|
||||||
|
github.com/matryer/is v1.4.0/go.mod h1:8I/i5uYgLzgsgEloJE1U6xx5HkBQpAZvepWuujKwMRU=
|
||||||
|
github.com/mattn/go-colorable v0.1.8/go.mod h1:u6P/XSegPjTcexA+o6vUJrdnUu04hMope9wVRipJSqc=
|
||||||
|
github.com/mattn/go-colorable v0.1.9/go.mod h1:u6P/XSegPjTcexA+o6vUJrdnUu04hMope9wVRipJSqc=
|
||||||
github.com/mattn/go-colorable v0.1.13 h1:fFA4WZxdEF4tXPZVKMLwD8oUnCTTo08duU7wxecdEvA=
|
github.com/mattn/go-colorable v0.1.13 h1:fFA4WZxdEF4tXPZVKMLwD8oUnCTTo08duU7wxecdEvA=
|
||||||
github.com/mattn/go-colorable v0.1.13/go.mod h1:7S9/ev0klgBDR4GtXTXX8a3vIGJpMovkB8vQcUbaXHg=
|
github.com/mattn/go-colorable v0.1.13/go.mod h1:7S9/ev0klgBDR4GtXTXX8a3vIGJpMovkB8vQcUbaXHg=
|
||||||
|
github.com/mattn/go-isatty v0.0.12/go.mod h1:cbi8OIDigv2wuxKPP5vlRcQ1OAZbq2CE4Kysco4FUpU=
|
||||||
|
github.com/mattn/go-isatty v0.0.14/go.mod h1:7GGIvUiUoEMVVmxf/4nioHXj79iQHKdU27kJ6hsGG94=
|
||||||
github.com/mattn/go-isatty v0.0.16/go.mod h1:kYGgaQfpe5nmfYZH+SKPsOc2e4SrIfOl2e/yFXSvRLM=
|
github.com/mattn/go-isatty v0.0.16/go.mod h1:kYGgaQfpe5nmfYZH+SKPsOc2e4SrIfOl2e/yFXSvRLM=
|
||||||
github.com/mattn/go-isatty v0.0.20 h1:xfD0iDuEKnDkl03q4limB+vH+GxLEtL/jb4xVJSWWEY=
|
github.com/mattn/go-isatty v0.0.20 h1:xfD0iDuEKnDkl03q4limB+vH+GxLEtL/jb4xVJSWWEY=
|
||||||
github.com/mattn/go-isatty v0.0.20/go.mod h1:W+V8PltTTMOvKvAeJH7IuucS94S2C6jfK/D7dTCTo3Y=
|
github.com/mattn/go-isatty v0.0.20/go.mod h1:W+V8PltTTMOvKvAeJH7IuucS94S2C6jfK/D7dTCTo3Y=
|
||||||
|
github.com/mattn/go-runewidth v0.0.13/go.mod h1:Jdepj2loyihRzMpdS35Xk/zdY8IAYHsh153qUoGf23w=
|
||||||
|
github.com/mitchellh/copystructure v1.2.0 h1:vpKXTN4ewci03Vljg/q9QvCGUDttBOGBIa15WveJJGw=
|
||||||
|
github.com/mitchellh/copystructure v1.2.0/go.mod h1:qLl+cE2AmVv+CoeAwDPye/v+N2HKCj9FbZEVFJRxO9s=
|
||||||
github.com/mitchellh/go-ps v1.0.0 h1:i6ampVEEF4wQFF+bkYfwYgY+F/uYJDktmvLPf7qIgjc=
|
github.com/mitchellh/go-ps v1.0.0 h1:i6ampVEEF4wQFF+bkYfwYgY+F/uYJDktmvLPf7qIgjc=
|
||||||
github.com/mitchellh/go-ps v1.0.0/go.mod h1:J4lOc8z8yJs6vUwklHw2XEIiT4z4C40KtWVN3nvg8Pg=
|
github.com/mitchellh/go-ps v1.0.0/go.mod h1:J4lOc8z8yJs6vUwklHw2XEIiT4z4C40KtWVN3nvg8Pg=
|
||||||
|
github.com/mitchellh/reflectwalk v1.0.2 h1:G2LzWKi524PWgd3mLHV8Y5k7s6XUvT0Gef6zxSIeXaQ=
|
||||||
|
github.com/mitchellh/reflectwalk v1.0.2/go.mod h1:mSTlrgnPZtwu0c4WaC2kGObEpuNDbx0jmZXqmk4esnw=
|
||||||
github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822 h1:C3w9PqII01/Oq1c1nUAm88MOHcQC9l5mIlSMApZMrHA=
|
github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822 h1:C3w9PqII01/Oq1c1nUAm88MOHcQC9l5mIlSMApZMrHA=
|
||||||
github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822/go.mod h1:+n7T8mK8HuQTcFwEeznm/DIxMOiR9yIdICNftLE1DvQ=
|
github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822/go.mod h1:+n7T8mK8HuQTcFwEeznm/DIxMOiR9yIdICNftLE1DvQ=
|
||||||
github.com/natefinch/atomic v1.0.1 h1:ZPYKxkqQOx3KZ+RsbnP/YsgvxWQPGxjC0oBt2AhwV0A=
|
github.com/natefinch/atomic v1.0.1 h1:ZPYKxkqQOx3KZ+RsbnP/YsgvxWQPGxjC0oBt2AhwV0A=
|
||||||
github.com/natefinch/atomic v1.0.1/go.mod h1:N/D/ELrljoqDyT3rZrsUmtsuzvHkeB/wWjHV22AZRbM=
|
github.com/natefinch/atomic v1.0.1/go.mod h1:N/D/ELrljoqDyT3rZrsUmtsuzvHkeB/wWjHV22AZRbM=
|
||||||
|
github.com/nbio/st v0.0.0-20140626010706-e9e8d9816f32/go.mod h1:9wM+0iRr9ahx58uYLpLIr5fm8diHn0JbqRycJi6w0Ms=
|
||||||
|
github.com/onsi/gomega v1.35.1 h1:Cwbd75ZBPxFSuZ6T+rN/WCb/gOc6YgFBXLlZLhC7Ds4=
|
||||||
|
github.com/onsi/gomega v1.35.1/go.mod h1:PvZbdDc8J6XJEpDK4HCuRBm8a6Fzp9/DmhC9C7yFlog=
|
||||||
|
github.com/pjbgf/sha1cd v0.3.2 h1:a9wb0bp1oC2TGwStyn0Umc/IGKQnEgF0vVaZ8QF8eo4=
|
||||||
|
github.com/pjbgf/sha1cd v0.3.2/go.mod h1:zQWigSxVmsHEZow5qaLtPYxpcKMMQpa09ixqBxuCS6A=
|
||||||
|
github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4=
|
||||||
|
github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
|
||||||
github.com/playwright-community/playwright-go v0.5200.0 h1:z/5LGuX2tBrg3ug1HupMXLjIG93f1d2MWdDsNhkMQ9c=
|
github.com/playwright-community/playwright-go v0.5200.0 h1:z/5LGuX2tBrg3ug1HupMXLjIG93f1d2MWdDsNhkMQ9c=
|
||||||
github.com/playwright-community/playwright-go v0.5200.0/go.mod h1:UnnyQZaqUOO5ywAZu60+N4EiWReUqX1MQBBA3Oofvf8=
|
github.com/playwright-community/playwright-go v0.5200.0/go.mod h1:UnnyQZaqUOO5ywAZu60+N4EiWReUqX1MQBBA3Oofvf8=
|
||||||
github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
|
|
||||||
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
|
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
|
||||||
|
github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2 h1:Jamvg5psRIccs7FGNTlIRMkT8wgtp5eCXdBlqhYGL6U=
|
||||||
|
github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
|
||||||
github.com/prometheus/client_golang v1.22.0 h1:rb93p9lokFEsctTys46VnV1kLCDpVZ0a/Y92Vm0Zc6Q=
|
github.com/prometheus/client_golang v1.22.0 h1:rb93p9lokFEsctTys46VnV1kLCDpVZ0a/Y92Vm0Zc6Q=
|
||||||
github.com/prometheus/client_golang v1.22.0/go.mod h1:R7ljNsLXhuQXYZYtw6GAE9AZg8Y7vEW5scdCXrWRXC0=
|
github.com/prometheus/client_golang v1.22.0/go.mod h1:R7ljNsLXhuQXYZYtw6GAE9AZg8Y7vEW5scdCXrWRXC0=
|
||||||
github.com/prometheus/client_model v0.6.1 h1:ZKSh/rekM+n3CeS952MLRAdFwIKqeY8b62p8ais2e9E=
|
github.com/prometheus/client_model v0.6.1 h1:ZKSh/rekM+n3CeS952MLRAdFwIKqeY8b62p8ais2e9E=
|
||||||
@@ -82,34 +230,68 @@ github.com/prometheus/common v0.62.0 h1:xasJaQlnWAeyHdUBeGjXmutelfJHWMRr+Fg4QszZ
|
|||||||
github.com/prometheus/common v0.62.0/go.mod h1:vyBcEuLSvWos9B1+CyL7JZ2up+uFzXhkqml0W5zIY1I=
|
github.com/prometheus/common v0.62.0/go.mod h1:vyBcEuLSvWos9B1+CyL7JZ2up+uFzXhkqml0W5zIY1I=
|
||||||
github.com/prometheus/procfs v0.15.1 h1:YagwOFzUgYfKKHX6Dr+sHT7km/hxC76UB0learggepc=
|
github.com/prometheus/procfs v0.15.1 h1:YagwOFzUgYfKKHX6Dr+sHT7km/hxC76UB0learggepc=
|
||||||
github.com/prometheus/procfs v0.15.1/go.mod h1:fB45yRUv8NstnjriLhBQLuOUt+WW4BsoGhij/e3PBqk=
|
github.com/prometheus/procfs v0.15.1/go.mod h1:fB45yRUv8NstnjriLhBQLuOUt+WW4BsoGhij/e3PBqk=
|
||||||
github.com/rogpeppe/go-internal v1.13.1 h1:KvO1DLK/DRN07sQ1LQKScxyZJuNnedQ5/wKSR38lUII=
|
github.com/redis/go-redis/v9 v9.8.0 h1:q3nRvjrlge/6UD7eTu/DSg2uYiU2mCL0G/uzBWqhicI=
|
||||||
github.com/rogpeppe/go-internal v1.13.1/go.mod h1:uMEvuHeurkdAXX61udpOXGD/AzZDWNMNyH2VO9fmH0o=
|
github.com/redis/go-redis/v9 v9.8.0/go.mod h1:huWgSWd8mW6+m0VPhJjSSQ+d6Nh1VICQ6Q5lHuCH/Iw=
|
||||||
|
github.com/rivo/uniseg v0.2.0/go.mod h1:J6wj4VEh+S6ZtnVlnTBMWIodfgj8LQOQFoIToxlJtxc=
|
||||||
|
github.com/rogpeppe/go-internal v1.14.1 h1:UQB4HGPB6osV0SQTLymcB4TgvyWu6ZyliaW0tI/otEQ=
|
||||||
|
github.com/rogpeppe/go-internal v1.14.1/go.mod h1:MaRKkUm5W0goXpeCfT7UZI6fk/L7L7so1lCWt35ZSgc=
|
||||||
|
github.com/sassoftware/go-rpmutils v0.4.0 h1:ojND82NYBxgwrV+mX1CWsd5QJvvEZTKddtCdFLPWhpg=
|
||||||
|
github.com/sassoftware/go-rpmutils v0.4.0/go.mod h1:3goNWi7PGAT3/dlql2lv3+MSN5jNYPjT5mVcQcIsYzI=
|
||||||
github.com/sebest/xff v0.0.0-20210106013422-671bd2870b3a h1:iLcLb5Fwwz7g/DLK89F+uQBDeAhHhwdzB5fSlVdhGcM=
|
github.com/sebest/xff v0.0.0-20210106013422-671bd2870b3a h1:iLcLb5Fwwz7g/DLK89F+uQBDeAhHhwdzB5fSlVdhGcM=
|
||||||
github.com/sebest/xff v0.0.0-20210106013422-671bd2870b3a/go.mod h1:wozgYq9WEBQBaIJe4YZ0qTSFAMxmcwBhQH0fO0R34Z0=
|
github.com/sebest/xff v0.0.0-20210106013422-671bd2870b3a/go.mod h1:wozgYq9WEBQBaIJe4YZ0qTSFAMxmcwBhQH0fO0R34Z0=
|
||||||
|
github.com/sergi/go-diff v1.3.2-0.20230802210424-5b0b94c5c0d3 h1:n661drycOFuPLCN3Uc8sB6B/s6Z4t2xvBgU1htSHuq8=
|
||||||
|
github.com/sergi/go-diff v1.3.2-0.20230802210424-5b0b94c5c0d3/go.mod h1:A0bzQcvG0E7Rwjx0REVgAGH58e96+X0MeOfepqsbeW4=
|
||||||
|
github.com/shopspring/decimal v1.4.0 h1:bxl37RwXBklmTi0C79JfXCEBD1cqqHt0bbgBAGFp81k=
|
||||||
|
github.com/shopspring/decimal v1.4.0/go.mod h1:gawqmDU56v4yIKSwfBSFip1HdCCXN8/+DMd9qYNcwME=
|
||||||
|
github.com/sirupsen/logrus v1.7.0/go.mod h1:yWOB1SBYBC5VeMP7gHvWumXLIWorT60ONWic61uBYv0=
|
||||||
|
github.com/skeema/knownhosts v1.3.1 h1:X2osQ+RAjK76shCbvhHHHVl3ZlgDm8apHEHFqRjnBY8=
|
||||||
|
github.com/skeema/knownhosts v1.3.1/go.mod h1:r7KTdC8l4uxWRyK2TpQZ/1o5HaSzh06ePQNxPwTcfiY=
|
||||||
|
github.com/smarty/assertions v1.15.0 h1:cR//PqUBUiQRakZWqBiFFQ9wb8emQGDb0HeGdqGByCY=
|
||||||
|
github.com/smarty/assertions v1.15.0/go.mod h1:yABtdzeQs6l1brC900WlRNwj6ZR55d7B+E8C6HtKdec=
|
||||||
|
github.com/smartystreets/goconvey v1.8.1 h1:qGjIddxOk4grTu9JPOU31tVfq3cNdBlNa5sSznIX1xY=
|
||||||
|
github.com/smartystreets/goconvey v1.8.1/go.mod h1:+/u4qLyY6x1jReYOp7GOM2FSt8aP9CzCZL03bI28W60=
|
||||||
|
github.com/spf13/cast v1.7.1 h1:cuNEagBQEHWN1FnbGEjCXL2szYEXqfJPbP2HNUaca9Y=
|
||||||
|
github.com/spf13/cast v1.7.1/go.mod h1:ancEpBxwJDODSW/UG4rDrAqiKolqNNh2DX3mk86cAdo=
|
||||||
github.com/stoewer/go-strcase v1.2.0 h1:Z2iHWqGXH00XYgqDmNgQbIBxf3wrNq0F3feEy0ainaU=
|
github.com/stoewer/go-strcase v1.2.0 h1:Z2iHWqGXH00XYgqDmNgQbIBxf3wrNq0F3feEy0ainaU=
|
||||||
github.com/stoewer/go-strcase v1.2.0/go.mod h1:IBiWB2sKIp3wVVQ3Y035++gc+knqhUQag1KpM8ahLw8=
|
github.com/stoewer/go-strcase v1.2.0/go.mod h1:IBiWB2sKIp3wVVQ3Y035++gc+knqhUQag1KpM8ahLw8=
|
||||||
github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
|
github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
|
||||||
|
github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs=
|
||||||
github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4=
|
github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4=
|
||||||
github.com/stretchr/testify v1.5.1/go.mod h1:5W2xD1RspED5o8YsWQXVCued0rvSQ+mT+I5cxcmMvtA=
|
github.com/stretchr/testify v1.5.1/go.mod h1:5W2xD1RspED5o8YsWQXVCued0rvSQ+mT+I5cxcmMvtA=
|
||||||
github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
|
github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
|
||||||
github.com/stretchr/testify v1.10.0 h1:Xv5erBjTwe/5IxqUQTdXv5kgmIvbHo3QQyRwhJsOfJA=
|
github.com/stretchr/testify v1.10.0 h1:Xv5erBjTwe/5IxqUQTdXv5kgmIvbHo3QQyRwhJsOfJA=
|
||||||
github.com/stretchr/testify v1.10.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY=
|
github.com/stretchr/testify v1.10.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY=
|
||||||
|
github.com/thlib/go-timezone-local v0.0.0-20210907160436-ef149e42d28e/go.mod h1:/Tnicc6m/lsJE0irFMA0LfIwTBo4QP7A8IfyIv4zZKI=
|
||||||
|
github.com/ulikunitz/xz v0.5.12 h1:37Nm15o69RwBkXM0J6A5OlE67RZTfzUxTj8fB3dfcsc=
|
||||||
|
github.com/ulikunitz/xz v0.5.12/go.mod h1:nbz6k7qbPmH4IRqmfOplQw/tblSgqTqBwxkY0oWt/14=
|
||||||
|
github.com/xanzy/ssh-agent v0.3.3 h1:+/15pJfg/RsTxqYcX6fHqOXZwwMP+2VyYWJeWM2qQFM=
|
||||||
|
github.com/xanzy/ssh-agent v0.3.3/go.mod h1:6dzNDKs0J9rVPHPhaGCukekBHKqfl+L3KghI1Bc68Uw=
|
||||||
|
github.com/xi2/xz v0.0.0-20171230120015-48954b6210f8 h1:nIPpBwaJSVYIxUFsDv3M8ofmx9yWTog9BfvIu0q41lo=
|
||||||
|
github.com/xi2/xz v0.0.0-20171230120015-48954b6210f8/go.mod h1:HUYIGzjTL3rfEspMxjDjgmT5uz5wzYJKVo23qUhYTos=
|
||||||
github.com/yl2chen/cidranger v1.0.2 h1:lbOWZVCG1tCRX4u24kuM1Tb4nHqWkDxwLdoS+SevawU=
|
github.com/yl2chen/cidranger v1.0.2 h1:lbOWZVCG1tCRX4u24kuM1Tb4nHqWkDxwLdoS+SevawU=
|
||||||
github.com/yl2chen/cidranger v1.0.2/go.mod h1:9U1yz7WPYDwf0vpNWFaeRh0bjwz5RVgRy/9UEQfHl0g=
|
github.com/yl2chen/cidranger v1.0.2/go.mod h1:9U1yz7WPYDwf0vpNWFaeRh0bjwz5RVgRy/9UEQfHl0g=
|
||||||
github.com/yuin/goldmark v1.4.13/go.mod h1:6yULJ656Px+3vBD8DxQVa3kxgyrAnzto9xy5taEt/CY=
|
github.com/yuin/goldmark v1.4.13/go.mod h1:6yULJ656Px+3vBD8DxQVa3kxgyrAnzto9xy5taEt/CY=
|
||||||
|
gitlab.com/digitalxero/go-conventional-commit v1.0.7 h1:8/dO6WWG+98PMhlZowt/YjuiKhqhGlOCwlIV8SqqGh8=
|
||||||
|
gitlab.com/digitalxero/go-conventional-commit v1.0.7/go.mod h1:05Xc2BFsSyC5tKhK0y+P3bs0AwUtNuTp+mTpbCU/DZ0=
|
||||||
golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
|
golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
|
||||||
|
golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
|
||||||
golang.org/x/crypto v0.0.0-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc=
|
golang.org/x/crypto v0.0.0-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc=
|
||||||
|
golang.org/x/crypto v0.0.0-20220622213112-05595931fe9d/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4=
|
||||||
golang.org/x/crypto v0.19.0/go.mod h1:Iy9bg/ha4yyC70EfRS8jz+B6ybOBKMaSxLj6P6oBDfU=
|
golang.org/x/crypto v0.19.0/go.mod h1:Iy9bg/ha4yyC70EfRS8jz+B6ybOBKMaSxLj6P6oBDfU=
|
||||||
golang.org/x/exp v0.0.0-20231110203233-9a3e6036ecaa h1:FRnLl4eNAQl8hwxVVC17teOw8kdjVDVAiFMtgUdTSRQ=
|
golang.org/x/crypto v0.38.0 h1:jt+WWG8IZlBnVbomuhg2Mdq0+BBQaHbtqHEFEigjUV8=
|
||||||
golang.org/x/exp v0.0.0-20231110203233-9a3e6036ecaa/go.mod h1:zk2irFbV9DP96SEBUUAy67IdHUaZuSnrz1n472HUCLE=
|
golang.org/x/crypto v0.38.0/go.mod h1:MvrbAqul58NNYPKnOra203SB9vpuZW0e+RRZV+Ggqjw=
|
||||||
|
golang.org/x/exp v0.0.0-20240719175910-8a7402abbf56 h1:2dVuKD2vS7b0QIHQbpyTISPd0LeHDbnYEryqj5Q1ug8=
|
||||||
|
golang.org/x/exp v0.0.0-20240719175910-8a7402abbf56/go.mod h1:M4RDyNAINzryxdtnbRXRL/OHtkFuWGRjvuhBJpk2IlY=
|
||||||
golang.org/x/exp/typeparams v0.0.0-20231108232855-2478ac86f678 h1:1P7xPZEwZMoBoz0Yze5Nx2/4pxj6nw9ZqHWXqP0iRgQ=
|
golang.org/x/exp/typeparams v0.0.0-20231108232855-2478ac86f678 h1:1P7xPZEwZMoBoz0Yze5Nx2/4pxj6nw9ZqHWXqP0iRgQ=
|
||||||
golang.org/x/exp/typeparams v0.0.0-20231108232855-2478ac86f678/go.mod h1:AbB0pIl9nAr9wVwH+Z2ZpaocVmF5I4GyWCDIsVjR0bk=
|
golang.org/x/exp/typeparams v0.0.0-20231108232855-2478ac86f678/go.mod h1:AbB0pIl9nAr9wVwH+Z2ZpaocVmF5I4GyWCDIsVjR0bk=
|
||||||
golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4/go.mod h1:jJ57K6gSWd91VN4djpZkiMVwK6gcyfeH4XE8wZrZaV4=
|
golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4/go.mod h1:jJ57K6gSWd91VN4djpZkiMVwK6gcyfeH4XE8wZrZaV4=
|
||||||
golang.org/x/mod v0.8.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs=
|
golang.org/x/mod v0.8.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs=
|
||||||
golang.org/x/mod v0.24.0 h1:ZfthKaKaT4NrhGVZHO1/WDTwGES4De8KtWO0SIbNJMU=
|
golang.org/x/mod v0.24.0 h1:ZfthKaKaT4NrhGVZHO1/WDTwGES4De8KtWO0SIbNJMU=
|
||||||
golang.org/x/mod v0.24.0/go.mod h1:IXM97Txy2VM4PJ3gI61r1YEk/gAj6zAHN3AdZt6S9Ww=
|
golang.org/x/mod v0.24.0/go.mod h1:IXM97Txy2VM4PJ3gI61r1YEk/gAj6zAHN3AdZt6S9Ww=
|
||||||
|
golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
|
||||||
golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
|
golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
|
||||||
golang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg=
|
golang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg=
|
||||||
|
golang.org/x/net v0.0.0-20211112202133-69e39bad7dc2/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y=
|
||||||
golang.org/x/net v0.0.0-20220722155237-a158d28d115b/go.mod h1:XRhObCWvk6IyKnWLug+ECip1KBveYUHfp+8e9klMJ9c=
|
golang.org/x/net v0.0.0-20220722155237-a158d28d115b/go.mod h1:XRhObCWvk6IyKnWLug+ECip1KBveYUHfp+8e9klMJ9c=
|
||||||
golang.org/x/net v0.6.0/go.mod h1:2Tu9+aMcznHK/AK1HMvgo6xiTLG5rD5rZLDS+rp2Bjs=
|
golang.org/x/net v0.6.0/go.mod h1:2Tu9+aMcznHK/AK1HMvgo6xiTLG5rD5rZLDS+rp2Bjs=
|
||||||
golang.org/x/net v0.10.0/go.mod h1:0qNGK6F8kojg2nk9dLZ2mShWaEBan6FAoqfSigmmuDg=
|
golang.org/x/net v0.10.0/go.mod h1:0qNGK6F8kojg2nk9dLZ2mShWaEBan6FAoqfSigmmuDg=
|
||||||
@@ -121,11 +303,22 @@ golang.org/x/sync v0.1.0/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
|||||||
golang.org/x/sync v0.14.0 h1:woo0S4Yywslg6hp4eUFjTVOyKt0RookbpAHG4c1HmhQ=
|
golang.org/x/sync v0.14.0 h1:woo0S4Yywslg6hp4eUFjTVOyKt0RookbpAHG4c1HmhQ=
|
||||||
golang.org/x/sync v0.14.0/go.mod h1:1dzgHSNfp02xaA81J2MS99Qcpr2w7fw1gpm99rleRqA=
|
golang.org/x/sync v0.14.0/go.mod h1:1dzgHSNfp02xaA81J2MS99Qcpr2w7fw1gpm99rleRqA=
|
||||||
golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
||||||
|
golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||||
|
golang.org/x/sys v0.0.0-20191026070338-33540a1f6037/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||||
|
golang.org/x/sys v0.0.0-20200116001909-b77594299b42/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||||
|
golang.org/x/sys v0.0.0-20200223170610-d5e6a3e2c0ae/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||||
golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||||
|
golang.org/x/sys v0.0.0-20210124154548-22da62e12c0c/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||||
|
golang.org/x/sys v0.0.0-20210319071255-635bc2c9138d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||||
|
golang.org/x/sys v0.0.0-20210423082822-04245dca01da/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||||
golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||||
|
golang.org/x/sys v0.0.0-20210630005230-0f9fa26af87c/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||||
|
golang.org/x/sys v0.0.0-20210831042530-f4d43177bf5e/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||||
golang.org/x/sys v0.0.0-20220520151302-bc2c85ada10a/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
golang.org/x/sys v0.0.0-20220520151302-bc2c85ada10a/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||||
|
golang.org/x/sys v0.0.0-20220715151400-c0bba94af5f8/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||||
golang.org/x/sys v0.0.0-20220722155257-8c9f86f7a55f/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
golang.org/x/sys v0.0.0-20220722155257-8c9f86f7a55f/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||||
golang.org/x/sys v0.0.0-20220811171246-fbc7d0a398ab/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
golang.org/x/sys v0.0.0-20220811171246-fbc7d0a398ab/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||||
|
golang.org/x/sys v0.0.0-20220818161305-2296e01440c6/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||||
golang.org/x/sys v0.5.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
golang.org/x/sys v0.5.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||||
golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||||
golang.org/x/sys v0.8.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
golang.org/x/sys v0.8.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||||
@@ -139,8 +332,12 @@ golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuX
|
|||||||
golang.org/x/term v0.5.0/go.mod h1:jMB1sMXY+tzblOD4FWmEbocvup2/aLOaQEp7JmGp78k=
|
golang.org/x/term v0.5.0/go.mod h1:jMB1sMXY+tzblOD4FWmEbocvup2/aLOaQEp7JmGp78k=
|
||||||
golang.org/x/term v0.8.0/go.mod h1:xPskH00ivmX89bAKVGSKKtLOWNx2+17Eiy94tnKShWo=
|
golang.org/x/term v0.8.0/go.mod h1:xPskH00ivmX89bAKVGSKKtLOWNx2+17Eiy94tnKShWo=
|
||||||
golang.org/x/term v0.17.0/go.mod h1:lLRBjIVuehSbZlaOtGMbcMncT+aqLLLmKrsjNrUguwk=
|
golang.org/x/term v0.17.0/go.mod h1:lLRBjIVuehSbZlaOtGMbcMncT+aqLLLmKrsjNrUguwk=
|
||||||
|
golang.org/x/term v0.32.0 h1:DR4lr0TjUs3epypdhTOkMmuF5CDFJ/8pOnbzMZPQ7bg=
|
||||||
|
golang.org/x/term v0.32.0/go.mod h1:uZG1FhGx848Sqfsq4/DlJr3xGGsYMu/L5GW4abiaEPQ=
|
||||||
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
|
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
|
||||||
|
golang.org/x/text v0.3.2/go.mod h1:bEr9sfX3Q8Zfm5fL9x+3itogRgK3+ptLWKqgva+5dAk=
|
||||||
golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
|
golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
|
||||||
|
golang.org/x/text v0.3.6/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
|
||||||
golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ=
|
golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ=
|
||||||
golang.org/x/text v0.7.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8=
|
golang.org/x/text v0.7.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8=
|
||||||
golang.org/x/text v0.9.0/go.mod h1:e1OnstbJyHTd6l/uOt8jFFHp6TRDWZR/bV3emEE/zU8=
|
golang.org/x/text v0.9.0/go.mod h1:e1OnstbJyHTd6l/uOt8jFFHp6TRDWZR/bV3emEE/zU8=
|
||||||
@@ -156,6 +353,10 @@ golang.org/x/tools v0.32.0/go.mod h1:ZxrU41P/wAbZD8EDa6dDCa6XfpkhJ7HFMjHJXfBDu8s
|
|||||||
golang.org/x/vuln v1.1.4 h1:Ju8QsuyhX3Hk8ma3CesTbO8vfJD9EvUBgHvkxHBzj0I=
|
golang.org/x/vuln v1.1.4 h1:Ju8QsuyhX3Hk8ma3CesTbO8vfJD9EvUBgHvkxHBzj0I=
|
||||||
golang.org/x/vuln v1.1.4/go.mod h1:F+45wmU18ym/ca5PLTPLsSzr2KppzswxPP603ldA67s=
|
golang.org/x/vuln v1.1.4/go.mod h1:F+45wmU18ym/ca5PLTPLsSzr2KppzswxPP603ldA67s=
|
||||||
golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
|
golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
|
||||||
|
golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
|
||||||
|
golang.org/x/xerrors v0.0.0-20220609144429-65e65417b02f/go.mod h1:K8+ghG5WaK9qNqU5K3HdILfMLy1f3aNYFI/wnl100a8=
|
||||||
|
golang.org/x/xerrors v0.0.0-20240716161551-93cc26a95ae9 h1:LLhsEBxRTBLuKlQxFBYUOU8xyFgXv6cOTp2HASDlsDk=
|
||||||
|
golang.org/x/xerrors v0.0.0-20240716161551-93cc26a95ae9/go.mod h1:NDW/Ps6MPRej6fsCIbMTohpP40sJ/P/vI1MoTEGwX90=
|
||||||
google.golang.org/genproto/googleapis/api v0.0.0-20240826202546-f6391c0de4c7 h1:YcyjlL1PRr2Q17/I0dPk2JmYS5CDXfcdb2Z3YRioEbw=
|
google.golang.org/genproto/googleapis/api v0.0.0-20240826202546-f6391c0de4c7 h1:YcyjlL1PRr2Q17/I0dPk2JmYS5CDXfcdb2Z3YRioEbw=
|
||||||
google.golang.org/genproto/googleapis/api v0.0.0-20240826202546-f6391c0de4c7/go.mod h1:OCdP9MfskevB/rbYvHTsXTtKC+3bHWajPdoKgjcYkfo=
|
google.golang.org/genproto/googleapis/api v0.0.0-20240826202546-f6391c0de4c7/go.mod h1:OCdP9MfskevB/rbYvHTsXTtKC+3bHWajPdoKgjcYkfo=
|
||||||
google.golang.org/genproto/googleapis/rpc v0.0.0-20240826202546-f6391c0de4c7 h1:2035KHhUv+EpyB+hWgJnaWKJOdX1E95w2S8Rr4uWKTs=
|
google.golang.org/genproto/googleapis/rpc v0.0.0-20240826202546-f6391c0de4c7 h1:2035KHhUv+EpyB+hWgJnaWKJOdX1E95w2S8Rr4uWKTs=
|
||||||
@@ -163,9 +364,16 @@ google.golang.org/genproto/googleapis/rpc v0.0.0-20240826202546-f6391c0de4c7/go.
|
|||||||
google.golang.org/protobuf v1.36.5 h1:tPhr+woSbjfYvY6/GPufUoYizxw1cF/yFoxJ2fmpwlM=
|
google.golang.org/protobuf v1.36.5 h1:tPhr+woSbjfYvY6/GPufUoYizxw1cF/yFoxJ2fmpwlM=
|
||||||
google.golang.org/protobuf v1.36.5/go.mod h1:9fA7Ob0pmnwhb644+1+CVWFRbNajQ6iRojtC/QF5bRE=
|
google.golang.org/protobuf v1.36.5/go.mod h1:9fA7Ob0pmnwhb644+1+CVWFRbNajQ6iRojtC/QF5bRE=
|
||||||
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
|
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
|
||||||
|
gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
|
||||||
|
gopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
|
||||||
gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c h1:Hei/4ADfdWqJk1ZMxUNpqntNwaWcugrBjAiHlqqRiVk=
|
gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c h1:Hei/4ADfdWqJk1ZMxUNpqntNwaWcugrBjAiHlqqRiVk=
|
||||||
gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c/go.mod h1:JHkPIbrfpd72SG/EVd6muEfDQjcINNoR0C8j2r3qZ4Q=
|
gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c/go.mod h1:JHkPIbrfpd72SG/EVd6muEfDQjcINNoR0C8j2r3qZ4Q=
|
||||||
|
gopkg.in/h2non/gock.v1 v1.1.2/go.mod h1:n7UGz/ckNChHiK05rDoiC4MYSunEC/lyaUm2WWaDva0=
|
||||||
|
gopkg.in/warnings.v0 v0.1.2 h1:wFXVbFY8DY5/xOe1ECiWdKCzZlxgshcYVNkBHstARME=
|
||||||
|
gopkg.in/warnings.v0 v0.1.2/go.mod h1:jksf8JmL6Qr/oQM2OXTHunEvvTAsrWBLb6OOjuVWRNI=
|
||||||
gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
|
gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
|
||||||
|
gopkg.in/yaml.v2 v2.4.0 h1:D8xgwECY7CYvx+Y2n4sBz93Jn9JRvxdiyyo8CTfuKaY=
|
||||||
|
gopkg.in/yaml.v2 v2.4.0/go.mod h1:RDklbk79AGWmwhnvt/jBztapEOGDOx6ZbXqjP6csGnQ=
|
||||||
gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
|
gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
|
||||||
gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA=
|
gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA=
|
||||||
gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
|
gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
|
||||||
@@ -173,6 +381,10 @@ honnef.co/go/tools v0.6.1 h1:R094WgE8K4JirYjBaOpz/AvTyUu/3wbmAoskKN/pxTI=
|
|||||||
honnef.co/go/tools v0.6.1/go.mod h1:3puzxxljPCe8RGJX7BIy1plGbxEOZni5mR2aXe3/uk4=
|
honnef.co/go/tools v0.6.1/go.mod h1:3puzxxljPCe8RGJX7BIy1plGbxEOZni5mR2aXe3/uk4=
|
||||||
k8s.io/apimachinery v0.33.0 h1:1a6kHrJxb2hs4t8EE5wuR/WxKDwGN1FKH3JvDtA0CIQ=
|
k8s.io/apimachinery v0.33.0 h1:1a6kHrJxb2hs4t8EE5wuR/WxKDwGN1FKH3JvDtA0CIQ=
|
||||||
k8s.io/apimachinery v0.33.0/go.mod h1:BHW0YOu7n22fFv/JkYOEfkUYNRN0fj0BlvMFWA7b+SM=
|
k8s.io/apimachinery v0.33.0/go.mod h1:BHW0YOu7n22fFv/JkYOEfkUYNRN0fj0BlvMFWA7b+SM=
|
||||||
|
pault.ag/go/debian v0.18.0 h1:nr0iiyOU5QlG1VPnhZLNhnCcHx58kukvBJp+dvaM6CQ=
|
||||||
|
pault.ag/go/debian v0.18.0/go.mod h1:JFl0XWRCv9hWBrB5MDDZjA5GSEs1X3zcFK/9kCNIUmE=
|
||||||
|
pault.ag/go/topsort v0.1.1 h1:L0QnhUly6LmTv0e3DEzbN2q6/FGgAcQvaEw65S53Bg4=
|
||||||
|
pault.ag/go/topsort v0.1.1/go.mod h1:r1kc/L0/FZ3HhjezBIPaNVhkqv8L0UJ9bxRuHRVZ0q4=
|
||||||
sigs.k8s.io/json v0.0.0-20241010143419-9aa6b5e7a4b3 h1:/Rv+M11QRah1itp8VhT6HoVx1Ray9eB4DBr+K+/sCJ8=
|
sigs.k8s.io/json v0.0.0-20241010143419-9aa6b5e7a4b3 h1:/Rv+M11QRah1itp8VhT6HoVx1Ray9eB4DBr+K+/sCJ8=
|
||||||
sigs.k8s.io/json v0.0.0-20241010143419-9aa6b5e7a4b3/go.mod h1:18nIHnGi6636UCz6m8i4DhaJ65T6EruyzmoQqI2BVDo=
|
sigs.k8s.io/json v0.0.0-20241010143419-9aa6b5e7a4b3/go.mod h1:18nIHnGi6636UCz6m8i4DhaJ65T6EruyzmoQqI2BVDo=
|
||||||
sigs.k8s.io/yaml v1.4.0 h1:Mk1wCc2gy/F0THH0TAp1QYyJNzRm2KCLy3o5ASXVI5E=
|
sigs.k8s.io/yaml v1.4.0 h1:Mk1wCc2gy/F0THH0TAp1QYyJNzRm2KCLy3o5ASXVI5E=
|
||||||
|
|||||||
@@ -158,12 +158,12 @@ func TestGetOGTagsWithHostConsideration(t *testing.T) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
testCases := []struct {
|
testCases := []struct {
|
||||||
name string
|
name string
|
||||||
ogCacheConsiderHost bool
|
requests []struct {
|
||||||
requests []struct {
|
|
||||||
host string
|
host string
|
||||||
expectedLoadCount int // Expected load count *after* this request
|
expectedLoadCount int
|
||||||
}
|
}
|
||||||
|
ogCacheConsiderHost bool // Expected load count *after* this request
|
||||||
}{
|
}{
|
||||||
{
|
{
|
||||||
name: "Host Not Considered - Same Host",
|
name: "Host Not Considered - Same Host",
|
||||||
|
|||||||
@@ -4,12 +4,13 @@ import (
|
|||||||
"context"
|
"context"
|
||||||
"errors"
|
"errors"
|
||||||
"fmt"
|
"fmt"
|
||||||
"golang.org/x/net/html"
|
|
||||||
"io"
|
"io"
|
||||||
"log/slog"
|
"log/slog"
|
||||||
"mime"
|
"mime"
|
||||||
"net"
|
"net"
|
||||||
"net/http"
|
"net/http"
|
||||||
|
|
||||||
|
"golang.org/x/net/html"
|
||||||
)
|
)
|
||||||
|
|
||||||
var (
|
var (
|
||||||
|
|||||||
@@ -2,7 +2,6 @@ package ogtags
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"fmt"
|
"fmt"
|
||||||
"golang.org/x/net/html"
|
|
||||||
"io"
|
"io"
|
||||||
"net/http"
|
"net/http"
|
||||||
"net/http/httptest"
|
"net/http/httptest"
|
||||||
@@ -10,6 +9,8 @@ import (
|
|||||||
"strings"
|
"strings"
|
||||||
"testing"
|
"testing"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
|
"golang.org/x/net/html"
|
||||||
)
|
)
|
||||||
|
|
||||||
func TestFetchHTMLDocument(t *testing.T) {
|
func TestFetchHTMLDocument(t *testing.T) {
|
||||||
|
|||||||
@@ -56,10 +56,10 @@ func TestIntegrationGetOGTags(t *testing.T) {
|
|||||||
|
|
||||||
// Test with different configurations
|
// Test with different configurations
|
||||||
testCases := []struct {
|
testCases := []struct {
|
||||||
|
expectedTags map[string]string
|
||||||
name string
|
name string
|
||||||
path string
|
path string
|
||||||
query string
|
query string
|
||||||
expectedTags map[string]string
|
|
||||||
expectError bool
|
expectError bool
|
||||||
}{
|
}{
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -20,12 +20,12 @@ const (
|
|||||||
type OGTagCache struct {
|
type OGTagCache struct {
|
||||||
cache *decaymap.Impl[string, map[string]string]
|
cache *decaymap.Impl[string, map[string]string]
|
||||||
targetURL *url.URL
|
targetURL *url.URL
|
||||||
ogCacheConsiderHost bool
|
client *http.Client
|
||||||
ogPassthrough bool
|
|
||||||
ogTimeToLive time.Duration
|
|
||||||
approvedTags []string
|
approvedTags []string
|
||||||
approvedPrefixes []string
|
approvedPrefixes []string
|
||||||
client *http.Client
|
ogTimeToLive time.Duration
|
||||||
|
ogCacheConsiderHost bool
|
||||||
|
ogPassthrough bool
|
||||||
}
|
}
|
||||||
|
|
||||||
func NewOGTagCache(target string, ogPassthrough bool, ogTimeToLive time.Duration, ogTagsConsiderHost bool) *OGTagCache {
|
func NewOGTagCache(target string, ogPassthrough bool, ogTimeToLive time.Duration, ogTagsConsiderHost bool) *OGTagCache {
|
||||||
|
|||||||
@@ -18,9 +18,9 @@ func TestExtractOGTags(t *testing.T) {
|
|||||||
testCache.approvedPrefixes = []string{"og:"}
|
testCache.approvedPrefixes = []string{"og:"}
|
||||||
|
|
||||||
tests := []struct {
|
tests := []struct {
|
||||||
|
expected map[string]string
|
||||||
name string
|
name string
|
||||||
htmlStr string
|
htmlStr string
|
||||||
expected map[string]string
|
|
||||||
}{
|
}{
|
||||||
{
|
{
|
||||||
name: "Basic OG tags", // Includes standard 'description' meta tag
|
name: "Basic OG tags", // Includes standard 'description' meta tag
|
||||||
|
|||||||
86
internal/store/valkey/valkey.go
Normal file
86
internal/store/valkey/valkey.go
Normal file
@@ -0,0 +1,86 @@
|
|||||||
|
package valkey
|
||||||
|
|
||||||
|
import (
|
||||||
|
"context"
|
||||||
|
"errors"
|
||||||
|
"fmt"
|
||||||
|
"strconv"
|
||||||
|
"strings"
|
||||||
|
|
||||||
|
valkey "github.com/redis/go-redis/v9"
|
||||||
|
)
|
||||||
|
|
||||||
|
type Store struct {
|
||||||
|
rdb *valkey.Client
|
||||||
|
}
|
||||||
|
|
||||||
|
func New(rdb *valkey.Client) *Store {
|
||||||
|
return &Store{rdb: rdb}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s *Store) Increment(ctx context.Context, segments []string) error {
|
||||||
|
key := fmt.Sprintf("anubis:%s", strings.Join(segments, ":"))
|
||||||
|
if err := s.rdb.Incr(ctx, key).Err(); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s *Store) GetInt(ctx context.Context, segments []string) (int, error) {
|
||||||
|
key := fmt.Sprintf("anubis:%s", strings.Join(segments, ":"))
|
||||||
|
numStr, err := s.rdb.Get(ctx, key).Result()
|
||||||
|
if err != nil {
|
||||||
|
return 0, err
|
||||||
|
}
|
||||||
|
|
||||||
|
num, err := strconv.Atoi(numStr)
|
||||||
|
if err != nil {
|
||||||
|
return 0, err
|
||||||
|
}
|
||||||
|
|
||||||
|
return num, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s *Store) MultiGetInt(ctx context.Context, segments [][]string) ([]int, error) {
|
||||||
|
var keys []string
|
||||||
|
for _, segment := range segments {
|
||||||
|
key := fmt.Sprintf("anubis:%s", strings.Join(segment, ":"))
|
||||||
|
keys = append(keys, key)
|
||||||
|
}
|
||||||
|
|
||||||
|
values, err := s.rdb.MGet(ctx, keys...).Result()
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
var errs []error
|
||||||
|
|
||||||
|
result := make([]int, len(values))
|
||||||
|
for i, val := range values {
|
||||||
|
if val == nil {
|
||||||
|
result[i] = 0
|
||||||
|
errs = append(errs, fmt.Errorf("can't get key %s: value is null", keys[i]))
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
|
||||||
|
switch v := val.(type) {
|
||||||
|
case string:
|
||||||
|
num, err := strconv.Atoi(v)
|
||||||
|
if err != nil {
|
||||||
|
errs = append(errs, fmt.Errorf("can't parse key %s: %w", keys[i], err))
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
|
||||||
|
result[i] = num
|
||||||
|
default:
|
||||||
|
errs = append(errs, fmt.Errorf("can't parse key %s: wanted type string but got type %T", keys[i], val))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if len(errs) != 0 {
|
||||||
|
return nil, fmt.Errorf("can't read from valkey: %w", errors.Join(errs...))
|
||||||
|
}
|
||||||
|
|
||||||
|
return result, nil
|
||||||
|
}
|
||||||
@@ -38,6 +38,7 @@ var (
|
|||||||
playwrightServer = flag.String("playwright", "ws://localhost:9001", "Playwright server URL")
|
playwrightServer = flag.String("playwright", "ws://localhost:9001", "Playwright server URL")
|
||||||
playwrightMaxTime = flag.Duration("playwright-max-time", 5*time.Second, "maximum time for Playwright requests")
|
playwrightMaxTime = flag.Duration("playwright-max-time", 5*time.Second, "maximum time for Playwright requests")
|
||||||
playwrightMaxHardTime = flag.Duration("playwright-max-hard-time", 5*time.Minute, "maximum time for hard Playwright requests")
|
playwrightMaxHardTime = flag.Duration("playwright-max-hard-time", 5*time.Minute, "maximum time for hard Playwright requests")
|
||||||
|
playwrightRunner = flag.String("playwright-runner", "npx", "how to start Playwright, can be: none,npx,docker,podman")
|
||||||
|
|
||||||
testCases = []testCase{
|
testCases = []testCase{
|
||||||
{
|
{
|
||||||
@@ -98,23 +99,24 @@ const (
|
|||||||
actionChallenge action = "CHALLENGE"
|
actionChallenge action = "CHALLENGE"
|
||||||
|
|
||||||
placeholderIP = "fd11:5ee:bad:c0de::"
|
placeholderIP = "fd11:5ee:bad:c0de::"
|
||||||
playwrightVersion = "1.51.1"
|
playwrightVersion = "1.52.0"
|
||||||
)
|
)
|
||||||
|
|
||||||
type action string
|
type action string
|
||||||
|
|
||||||
type testCase struct {
|
type testCase struct {
|
||||||
name string
|
name string
|
||||||
action action
|
action action
|
||||||
isHard bool
|
realIP string
|
||||||
realIP, userAgent string
|
userAgent string
|
||||||
|
isHard bool
|
||||||
}
|
}
|
||||||
|
|
||||||
func doesNPXExist(t *testing.T) {
|
func doesCommandExist(t *testing.T, command string) {
|
||||||
t.Helper()
|
t.Helper()
|
||||||
|
|
||||||
if _, err := exec.LookPath("npx"); err != nil {
|
if _, err := exec.LookPath(command); err != nil {
|
||||||
t.Skipf("npx not found in PATH, skipping integration smoke testing: %v", err)
|
t.Skipf("%s not found in PATH, skipping integration smoke testing: %v", command, err)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -169,13 +171,30 @@ func daemonize(t *testing.T, command string) {
|
|||||||
func startPlaywright(t *testing.T) {
|
func startPlaywright(t *testing.T) {
|
||||||
t.Helper()
|
t.Helper()
|
||||||
|
|
||||||
if os.Getenv("CI") == "true" {
|
if *playwrightRunner == "npx" {
|
||||||
run(t, fmt.Sprintf("npx --yes playwright@%s install --with-deps", playwrightVersion))
|
doesCommandExist(t, "npx")
|
||||||
} else {
|
|
||||||
run(t, fmt.Sprintf("npx --yes playwright@%s install", playwrightVersion))
|
|
||||||
}
|
|
||||||
|
|
||||||
daemonize(t, fmt.Sprintf("npx --yes playwright@%s run-server --port %d", playwrightVersion, *playwrightPort))
|
if os.Getenv("CI") == "true" {
|
||||||
|
run(t, fmt.Sprintf("npx --yes playwright@%s install --with-deps", playwrightVersion))
|
||||||
|
} else {
|
||||||
|
run(t, fmt.Sprintf("npx --yes playwright@%s install", playwrightVersion))
|
||||||
|
}
|
||||||
|
|
||||||
|
daemonize(t, fmt.Sprintf("npx --yes playwright@%s run-server --port %d", playwrightVersion, *playwrightPort))
|
||||||
|
} else if *playwrightRunner == "docker" || *playwrightRunner == "podman" {
|
||||||
|
doesCommandExist(t, *playwrightRunner)
|
||||||
|
|
||||||
|
// docs: https://playwright.dev/docs/docker
|
||||||
|
pwcmd := fmt.Sprintf("npx -y playwright@%s run-server --port %d --host 0.0.0.0", playwrightVersion, *playwrightPort)
|
||||||
|
container := run(t, fmt.Sprintf("%s run -d --ipc=host --user pwuser --workdir /home/pwuser --net=host mcr.microsoft.com/playwright:v%s-noble /bin/sh -c \"%s\"", *playwrightRunner, playwrightVersion, pwcmd))
|
||||||
|
t.Cleanup(func() {
|
||||||
|
run(t, fmt.Sprintf("%s rm --force %s", *playwrightRunner, container))
|
||||||
|
})
|
||||||
|
} else if *playwrightRunner == "none" {
|
||||||
|
t.Log("not starting Playwright, assuming it is already running")
|
||||||
|
} else {
|
||||||
|
t.Skipf("unknown runner: %s, skipping", *playwrightRunner)
|
||||||
|
}
|
||||||
|
|
||||||
for {
|
for {
|
||||||
if _, err := http.Get(fmt.Sprintf("http://localhost:%d", *playwrightPort)); err != nil {
|
if _, err := http.Get(fmt.Sprintf("http://localhost:%d", *playwrightPort)); err != nil {
|
||||||
@@ -195,7 +214,6 @@ func TestPlaywrightBrowser(t *testing.T) {
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
doesNPXExist(t)
|
|
||||||
startPlaywright(t)
|
startPlaywright(t)
|
||||||
|
|
||||||
pw := setupPlaywright(t)
|
pw := setupPlaywright(t)
|
||||||
@@ -273,7 +291,6 @@ func TestPlaywrightWithBasePrefix(t *testing.T) {
|
|||||||
|
|
||||||
t.Skip("NOTE(Xe)\\ these tests require HTTPS support in #364")
|
t.Skip("NOTE(Xe)\\ these tests require HTTPS support in #364")
|
||||||
|
|
||||||
doesNPXExist(t)
|
|
||||||
startPlaywright(t)
|
startPlaywright(t)
|
||||||
|
|
||||||
pw := setupPlaywright(t)
|
pw := setupPlaywright(t)
|
||||||
|
|||||||
@@ -65,12 +65,12 @@ func TestXForwardedForUpdateAddToChain(t *testing.T) {
|
|||||||
|
|
||||||
func TestComputeXFFHeader(t *testing.T) {
|
func TestComputeXFFHeader(t *testing.T) {
|
||||||
for _, tt := range []struct {
|
for _, tt := range []struct {
|
||||||
|
err error
|
||||||
name string
|
name string
|
||||||
remoteAddr string
|
remoteAddr string
|
||||||
origXFFHeader string
|
origXFFHeader string
|
||||||
pref XFFComputePreferences
|
|
||||||
result string
|
result string
|
||||||
err error
|
pref XFFComputePreferences
|
||||||
}{
|
}{
|
||||||
{
|
{
|
||||||
name: "StripPrivate",
|
name: "StripPrivate",
|
||||||
|
|||||||
@@ -17,6 +17,7 @@ import (
|
|||||||
"time"
|
"time"
|
||||||
|
|
||||||
"github.com/golang-jwt/jwt/v5"
|
"github.com/golang-jwt/jwt/v5"
|
||||||
|
|
||||||
"github.com/prometheus/client_golang/prometheus"
|
"github.com/prometheus/client_golang/prometheus"
|
||||||
"github.com/prometheus/client_golang/prometheus/promauto"
|
"github.com/prometheus/client_golang/prometheus/promauto"
|
||||||
|
|
||||||
@@ -25,6 +26,7 @@ import (
|
|||||||
"github.com/TecharoHQ/anubis/internal"
|
"github.com/TecharoHQ/anubis/internal"
|
||||||
"github.com/TecharoHQ/anubis/internal/dnsbl"
|
"github.com/TecharoHQ/anubis/internal/dnsbl"
|
||||||
"github.com/TecharoHQ/anubis/internal/ogtags"
|
"github.com/TecharoHQ/anubis/internal/ogtags"
|
||||||
|
"github.com/TecharoHQ/anubis/internal/store/valkey"
|
||||||
"github.com/TecharoHQ/anubis/lib/policy"
|
"github.com/TecharoHQ/anubis/lib/policy"
|
||||||
"github.com/TecharoHQ/anubis/lib/policy/config"
|
"github.com/TecharoHQ/anubis/lib/policy/config"
|
||||||
)
|
)
|
||||||
@@ -58,14 +60,16 @@ var (
|
|||||||
)
|
)
|
||||||
|
|
||||||
type Server struct {
|
type Server struct {
|
||||||
mux *http.ServeMux
|
|
||||||
next http.Handler
|
next http.Handler
|
||||||
priv ed25519.PrivateKey
|
mux *http.ServeMux
|
||||||
pub ed25519.PublicKey
|
|
||||||
policy *policy.ParsedConfig
|
policy *policy.ParsedConfig
|
||||||
opts Options
|
|
||||||
DNSBLCache *decaymap.Impl[string, dnsbl.DroneBLResponse]
|
DNSBLCache *decaymap.Impl[string, dnsbl.DroneBLResponse]
|
||||||
OGTags *ogtags.OGTagCache
|
OGTags *ogtags.OGTagCache
|
||||||
|
priv ed25519.PrivateKey
|
||||||
|
pub ed25519.PublicKey
|
||||||
|
opts Options
|
||||||
|
cookieName string
|
||||||
|
store *valkey.Store
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *Server) challengeFor(r *http.Request, difficulty int) string {
|
func (s *Server) challengeFor(r *http.Request, difficulty int) string {
|
||||||
@@ -116,7 +120,7 @@ func (s *Server) maybeReverseProxy(w http.ResponseWriter, r *http.Request, httpS
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
ckie, err := r.Cookie(anubis.CookieName)
|
ckie, err := r.Cookie(s.cookieName)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
lg.Debug("cookie not found", "path", r.URL.Path)
|
lg.Debug("cookie not found", "path", r.URL.Path)
|
||||||
s.ClearCookie(w)
|
s.ClearCookie(w)
|
||||||
@@ -231,9 +235,13 @@ func (s *Server) MakeChallenge(w http.ResponseWriter, r *http.Request) {
|
|||||||
lg = lg.With("check_result", cr)
|
lg = lg.With("check_result", cr)
|
||||||
challenge := s.challengeFor(r, rule.Challenge.Difficulty)
|
challenge := s.challengeFor(r, rule.Challenge.Difficulty)
|
||||||
|
|
||||||
|
if s.store != nil {
|
||||||
|
s.store.Increment(r.Context(), []string{"pass_rate", "User-Agent", r.UserAgent(), "challenges_issued"})
|
||||||
|
}
|
||||||
|
|
||||||
err = encoder.Encode(struct {
|
err = encoder.Encode(struct {
|
||||||
Challenge string `json:"challenge"`
|
|
||||||
Rules *config.ChallengeRules `json:"rules"`
|
Rules *config.ChallengeRules `json:"rules"`
|
||||||
|
Challenge string `json:"challenge"`
|
||||||
}{
|
}{
|
||||||
Challenge: challenge,
|
Challenge: challenge,
|
||||||
Rules: rule.Challenge,
|
Rules: rule.Challenge,
|
||||||
@@ -323,6 +331,9 @@ func (s *Server) PassChallenge(w http.ResponseWriter, r *http.Request) {
|
|||||||
s.ClearCookie(w)
|
s.ClearCookie(w)
|
||||||
lg.Debug("hash does not match", "got", response, "want", calculated)
|
lg.Debug("hash does not match", "got", response, "want", calculated)
|
||||||
s.respondWithStatus(w, r, "invalid response", http.StatusForbidden)
|
s.respondWithStatus(w, r, "invalid response", http.StatusForbidden)
|
||||||
|
if s.store != nil {
|
||||||
|
s.store.Increment(r.Context(), []string{"pass_rate", "User-Agent", r.UserAgent(), "fail"})
|
||||||
|
}
|
||||||
failedValidations.Inc()
|
failedValidations.Inc()
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
@@ -332,6 +343,9 @@ func (s *Server) PassChallenge(w http.ResponseWriter, r *http.Request) {
|
|||||||
s.ClearCookie(w)
|
s.ClearCookie(w)
|
||||||
lg.Debug("difficulty check failed", "response", response, "difficulty", rule.Challenge.Difficulty)
|
lg.Debug("difficulty check failed", "response", response, "difficulty", rule.Challenge.Difficulty)
|
||||||
s.respondWithStatus(w, r, "invalid response", http.StatusForbidden)
|
s.respondWithStatus(w, r, "invalid response", http.StatusForbidden)
|
||||||
|
if s.store != nil {
|
||||||
|
s.store.Increment(r.Context(), []string{"pass_rate", "User-Agent", r.UserAgent(), "fail"})
|
||||||
|
}
|
||||||
failedValidations.Inc()
|
failedValidations.Inc()
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
@@ -344,7 +358,7 @@ func (s *Server) PassChallenge(w http.ResponseWriter, r *http.Request) {
|
|||||||
// generate JWT cookie
|
// generate JWT cookie
|
||||||
token := jwt.NewWithClaims(jwt.SigningMethodEdDSA, jwt.MapClaims{
|
token := jwt.NewWithClaims(jwt.SigningMethodEdDSA, jwt.MapClaims{
|
||||||
"challenge": challenge,
|
"challenge": challenge,
|
||||||
"nonce": nonce,
|
"nonce": nonceStr,
|
||||||
"response": response,
|
"response": response,
|
||||||
"iat": time.Now().Unix(),
|
"iat": time.Now().Unix(),
|
||||||
"nbf": time.Now().Add(-1 * time.Minute).Unix(),
|
"nbf": time.Now().Add(-1 * time.Minute).Unix(),
|
||||||
@@ -359,7 +373,7 @@ func (s *Server) PassChallenge(w http.ResponseWriter, r *http.Request) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
http.SetCookie(w, &http.Cookie{
|
http.SetCookie(w, &http.Cookie{
|
||||||
Name: anubis.CookieName,
|
Name: s.cookieName,
|
||||||
Value: tokenString,
|
Value: tokenString,
|
||||||
Expires: time.Now().Add(s.opts.CookieExpiration),
|
Expires: time.Now().Add(s.opts.CookieExpiration),
|
||||||
SameSite: http.SameSiteLaxMode,
|
SameSite: http.SameSiteLaxMode,
|
||||||
@@ -368,6 +382,10 @@ func (s *Server) PassChallenge(w http.ResponseWriter, r *http.Request) {
|
|||||||
Path: cookiePath,
|
Path: cookiePath,
|
||||||
})
|
})
|
||||||
|
|
||||||
|
if s.store != nil {
|
||||||
|
s.store.Increment(r.Context(), []string{"pass_rate", "User-Agent", r.UserAgent(), "pass"})
|
||||||
|
}
|
||||||
|
|
||||||
challengesValidated.Inc()
|
challengesValidated.Inc()
|
||||||
lg.Debug("challenge passed, redirecting to app")
|
lg.Debug("challenge passed, redirecting to app")
|
||||||
http.Redirect(w, r, redir, http.StatusFound)
|
http.Redirect(w, r, redir, http.StatusFound)
|
||||||
@@ -397,6 +415,8 @@ func (s *Server) check(r *http.Request) (policy.CheckResult, *policy.Bot, error)
|
|||||||
return decaymap.Zilch[policy.CheckResult](), nil, fmt.Errorf("[misconfiguration] %q is not an IP address", host)
|
return decaymap.Zilch[policy.CheckResult](), nil, fmt.Errorf("[misconfiguration] %q is not an IP address", host)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
weight := 0
|
||||||
|
|
||||||
for _, b := range s.policy.Bots {
|
for _, b := range s.policy.Bots {
|
||||||
match, err := b.Rules.Check(r)
|
match, err := b.Rules.Check(r)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@@ -404,10 +424,27 @@ func (s *Server) check(r *http.Request) (policy.CheckResult, *policy.Bot, error)
|
|||||||
}
|
}
|
||||||
|
|
||||||
if match {
|
if match {
|
||||||
return cr("bot/"+b.Name, b.Action), &b, nil
|
switch b.Action {
|
||||||
|
case config.RuleDeny, config.RuleAllow, config.RuleBenchmark:
|
||||||
|
return cr("bot/"+b.Name, b.Action), &b, nil
|
||||||
|
case config.RuleChallenge:
|
||||||
|
weight += 5
|
||||||
|
case config.RuleWeigh:
|
||||||
|
weight += b.Weight.Adjust
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if weight < 0 {
|
||||||
|
return cr("weight/okay", config.RuleAllow), &policy.Bot{
|
||||||
|
Challenge: &config.ChallengeRules{
|
||||||
|
Difficulty: s.policy.DefaultDifficulty,
|
||||||
|
ReportAs: s.policy.DefaultDifficulty,
|
||||||
|
Algorithm: config.AlgorithmFast,
|
||||||
|
},
|
||||||
|
}, nil
|
||||||
|
}
|
||||||
|
|
||||||
return cr("default/allow", config.RuleAllow), &policy.Bot{
|
return cr("default/allow", config.RuleAllow), &policy.Bot{
|
||||||
Challenge: &config.ChallengeRules{
|
Challenge: &config.ChallengeRules{
|
||||||
Difficulty: s.policy.DefaultDifficulty,
|
Difficulty: s.policy.DefaultDifficulty,
|
||||||
|
|||||||
@@ -198,13 +198,13 @@ func TestCookieCustomExpiration(t *testing.T) {
|
|||||||
var ckie *http.Cookie
|
var ckie *http.Cookie
|
||||||
for _, cookie := range resp.Cookies() {
|
for _, cookie := range resp.Cookies() {
|
||||||
t.Logf("%#v", cookie)
|
t.Logf("%#v", cookie)
|
||||||
if cookie.Name == anubis.CookieName {
|
if cookie.Name == srv.cookieName {
|
||||||
ckie = cookie
|
ckie = cookie
|
||||||
break
|
break
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if ckie == nil {
|
if ckie == nil {
|
||||||
t.Errorf("Cookie %q not found", anubis.CookieName)
|
t.Errorf("Cookie %q not found", srv.cookieName)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -288,13 +288,13 @@ func TestCookieSettings(t *testing.T) {
|
|||||||
var ckie *http.Cookie
|
var ckie *http.Cookie
|
||||||
for _, cookie := range resp.Cookies() {
|
for _, cookie := range resp.Cookies() {
|
||||||
t.Logf("%#v", cookie)
|
t.Logf("%#v", cookie)
|
||||||
if cookie.Name == anubis.CookieName {
|
if cookie.Name == srv.cookieName {
|
||||||
ckie = cookie
|
ckie = cookie
|
||||||
break
|
break
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if ckie == nil {
|
if ckie == nil {
|
||||||
t.Errorf("Cookie %q not found", anubis.CookieName)
|
t.Errorf("Cookie %q not found", srv.cookieName)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -23,24 +23,21 @@ import (
|
|||||||
)
|
)
|
||||||
|
|
||||||
type Options struct {
|
type Options struct {
|
||||||
Next http.Handler
|
Next http.Handler
|
||||||
Policy *policy.ParsedConfig
|
Policy *policy.ParsedConfig
|
||||||
RedirectDomains []string
|
Target string
|
||||||
ServeRobotsTXT bool
|
CookieDomain string
|
||||||
PrivateKey ed25519.PrivateKey
|
CookieName string
|
||||||
|
BasePrefix string
|
||||||
CookieExpiration time.Duration
|
WebmasterEmail string
|
||||||
CookieDomain string
|
RedirectDomains []string
|
||||||
CookieName string
|
PrivateKey ed25519.PrivateKey
|
||||||
CookiePartitioned bool
|
CookieExpiration time.Duration
|
||||||
|
|
||||||
OGPassthrough bool
|
|
||||||
OGTimeToLive time.Duration
|
OGTimeToLive time.Duration
|
||||||
OGCacheConsidersHost bool
|
OGCacheConsidersHost bool
|
||||||
Target string
|
OGPassthrough bool
|
||||||
|
CookiePartitioned bool
|
||||||
WebmasterEmail string
|
ServeRobotsTXT bool
|
||||||
BasePrefix string
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func LoadPoliciesOrDefault(fname string, defaultDifficulty int) (*policy.ParsedConfig, error) {
|
func LoadPoliciesOrDefault(fname string, defaultDifficulty int) (*policy.ParsedConfig, error) {
|
||||||
@@ -84,6 +81,12 @@ func New(opts Options) (*Server, error) {
|
|||||||
|
|
||||||
anubis.BasePrefix = opts.BasePrefix
|
anubis.BasePrefix = opts.BasePrefix
|
||||||
|
|
||||||
|
cookieName := anubis.CookieName
|
||||||
|
|
||||||
|
if opts.CookieDomain != "" {
|
||||||
|
cookieName = anubis.WithDomainCookieName + opts.CookieDomain
|
||||||
|
}
|
||||||
|
|
||||||
result := &Server{
|
result := &Server{
|
||||||
next: opts.Next,
|
next: opts.Next,
|
||||||
priv: opts.PrivateKey,
|
priv: opts.PrivateKey,
|
||||||
@@ -92,6 +95,7 @@ func New(opts Options) (*Server, error) {
|
|||||||
opts: opts,
|
opts: opts,
|
||||||
DNSBLCache: decaymap.New[string, dnsbl.DroneBLResponse](),
|
DNSBLCache: decaymap.New[string, dnsbl.DroneBLResponse](),
|
||||||
OGTags: ogtags.NewOGTagCache(opts.Target, opts.OGPassthrough, opts.OGTimeToLive, opts.OGCacheConsidersHost),
|
OGTags: ogtags.NewOGTagCache(opts.Target, opts.OGPassthrough, opts.OGTimeToLive, opts.OGCacheConsidersHost),
|
||||||
|
cookieName: cookieName,
|
||||||
}
|
}
|
||||||
|
|
||||||
mux := http.NewServeMux()
|
mux := http.NewServeMux()
|
||||||
|
|||||||
@@ -9,13 +9,11 @@ import (
|
|||||||
"github.com/TecharoHQ/anubis/lib/policy"
|
"github.com/TecharoHQ/anubis/lib/policy"
|
||||||
"github.com/TecharoHQ/anubis/web"
|
"github.com/TecharoHQ/anubis/web"
|
||||||
"github.com/a-h/templ"
|
"github.com/a-h/templ"
|
||||||
|
|
||||||
"github.com/TecharoHQ/anubis"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
func (s *Server) ClearCookie(w http.ResponseWriter) {
|
func (s *Server) ClearCookie(w http.ResponseWriter) {
|
||||||
http.SetCookie(w, &http.Cookie{
|
http.SetCookie(w, &http.Cookie{
|
||||||
Name: anubis.CookieName,
|
Name: s.cookieName,
|
||||||
Value: "",
|
Value: "",
|
||||||
Expires: time.Now().Add(-1 * time.Hour),
|
Expires: time.Now().Add(-1 * time.Hour),
|
||||||
MaxAge: -1,
|
MaxAge: -1,
|
||||||
@@ -67,6 +65,10 @@ func (s *Server) RenderIndex(w http.ResponseWriter, r *http.Request, rule *polic
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if s.store != nil {
|
||||||
|
s.store.Increment(r.Context(), []string{"pass_rate", "User-Agent", r.UserAgent(), "challenges_issued"})
|
||||||
|
}
|
||||||
|
|
||||||
handler := internal.NoStoreCache(templ.Handler(
|
handler := internal.NoStoreCache(templ.Handler(
|
||||||
component,
|
component,
|
||||||
templ.WithStatus(s.opts.Policy.StatusCodes.Challenge),
|
templ.WithStatus(s.opts.Policy.StatusCodes.Challenge),
|
||||||
|
|||||||
58
lib/http_test.go
Normal file
58
lib/http_test.go
Normal file
@@ -0,0 +1,58 @@
|
|||||||
|
package lib
|
||||||
|
|
||||||
|
import (
|
||||||
|
"net/http/httptest"
|
||||||
|
"testing"
|
||||||
|
|
||||||
|
"github.com/TecharoHQ/anubis"
|
||||||
|
)
|
||||||
|
|
||||||
|
func TestClearCookie(t *testing.T) {
|
||||||
|
srv := spawnAnubis(t, Options{})
|
||||||
|
rw := httptest.NewRecorder()
|
||||||
|
|
||||||
|
srv.ClearCookie(rw)
|
||||||
|
|
||||||
|
resp := rw.Result()
|
||||||
|
|
||||||
|
cookies := resp.Cookies()
|
||||||
|
|
||||||
|
if len(cookies) != 1 {
|
||||||
|
t.Errorf("wanted 1 cookie, got %d cookies", len(cookies))
|
||||||
|
}
|
||||||
|
|
||||||
|
ckie := cookies[0]
|
||||||
|
|
||||||
|
if ckie.Name != anubis.CookieName {
|
||||||
|
t.Errorf("wanted cookie named %q, got cookie named %q", anubis.CookieName, ckie.Name)
|
||||||
|
}
|
||||||
|
|
||||||
|
if ckie.MaxAge != -1 {
|
||||||
|
t.Errorf("wanted cookie max age of -1, got: %d", ckie.MaxAge)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestClearCookieWithDomain(t *testing.T) {
|
||||||
|
srv := spawnAnubis(t, Options{CookieDomain: "techaro.lol"})
|
||||||
|
rw := httptest.NewRecorder()
|
||||||
|
|
||||||
|
srv.ClearCookie(rw)
|
||||||
|
|
||||||
|
resp := rw.Result()
|
||||||
|
|
||||||
|
cookies := resp.Cookies()
|
||||||
|
|
||||||
|
if len(cookies) != 1 {
|
||||||
|
t.Errorf("wanted 1 cookie, got %d cookies", len(cookies))
|
||||||
|
}
|
||||||
|
|
||||||
|
ckie := cookies[0]
|
||||||
|
|
||||||
|
if ckie.Name != srv.cookieName {
|
||||||
|
t.Errorf("wanted cookie named %q, got cookie named %q", srv.cookieName, ckie.Name)
|
||||||
|
}
|
||||||
|
|
||||||
|
if ckie.MaxAge != -1 {
|
||||||
|
t.Errorf("wanted cookie max age of -1, got: %d", ckie.MaxAge)
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -8,10 +8,11 @@ import (
|
|||||||
)
|
)
|
||||||
|
|
||||||
type Bot struct {
|
type Bot struct {
|
||||||
|
Rules Checker
|
||||||
|
Challenge *config.ChallengeRules
|
||||||
Name string
|
Name string
|
||||||
Action config.Rule
|
Action config.Rule
|
||||||
Challenge *config.ChallengeRules
|
Weight *config.Weight
|
||||||
Rules Checker
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func (b Bot) Hash() string {
|
func (b Bot) Hash() string {
|
||||||
|
|||||||
@@ -12,8 +12,8 @@ import (
|
|||||||
)
|
)
|
||||||
|
|
||||||
type CELChecker struct {
|
type CELChecker struct {
|
||||||
src string
|
|
||||||
program cel.Program
|
program cel.Program
|
||||||
|
src string
|
||||||
}
|
}
|
||||||
|
|
||||||
func NewCELChecker(cfg *config.ExpressionOrList) (*CELChecker, error) {
|
func NewCELChecker(cfg *config.ExpressionOrList) (*CELChecker, error) {
|
||||||
|
|||||||
@@ -8,11 +8,11 @@ import (
|
|||||||
|
|
||||||
func TestRemoteAddrChecker(t *testing.T) {
|
func TestRemoteAddrChecker(t *testing.T) {
|
||||||
for _, tt := range []struct {
|
for _, tt := range []struct {
|
||||||
name string
|
|
||||||
cidrs []string
|
|
||||||
ip string
|
|
||||||
ok bool
|
|
||||||
err error
|
err error
|
||||||
|
name string
|
||||||
|
ip string
|
||||||
|
cidrs []string
|
||||||
|
ok bool
|
||||||
}{
|
}{
|
||||||
{
|
{
|
||||||
name: "match_ipv4",
|
name: "match_ipv4",
|
||||||
@@ -86,13 +86,13 @@ func TestRemoteAddrChecker(t *testing.T) {
|
|||||||
|
|
||||||
func TestHeaderMatchesChecker(t *testing.T) {
|
func TestHeaderMatchesChecker(t *testing.T) {
|
||||||
for _, tt := range []struct {
|
for _, tt := range []struct {
|
||||||
|
err error
|
||||||
name string
|
name string
|
||||||
header string
|
header string
|
||||||
rexStr string
|
rexStr string
|
||||||
reqHeaderKey string
|
reqHeaderKey string
|
||||||
reqHeaderValue string
|
reqHeaderValue string
|
||||||
ok bool
|
ok bool
|
||||||
err error
|
|
||||||
}{
|
}{
|
||||||
{
|
{
|
||||||
name: "match",
|
name: "match",
|
||||||
|
|||||||
@@ -7,12 +7,15 @@ import (
|
|||||||
)
|
)
|
||||||
|
|
||||||
type CheckResult struct {
|
type CheckResult struct {
|
||||||
Name string
|
Name string
|
||||||
Rule config.Rule
|
Rule config.Rule
|
||||||
|
Weight int
|
||||||
}
|
}
|
||||||
|
|
||||||
func (cr CheckResult) LogValue() slog.Value {
|
func (cr CheckResult) LogValue() slog.Value {
|
||||||
return slog.GroupValue(
|
return slog.GroupValue(
|
||||||
slog.String("name", cr.Name),
|
slog.String("name", cr.Name),
|
||||||
slog.String("rule", string(cr.Rule)))
|
slog.String("rule", string(cr.Rule)),
|
||||||
|
slog.Int("weight", cr.Weight),
|
||||||
|
)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -39,6 +39,7 @@ const (
|
|||||||
RuleAllow Rule = "ALLOW"
|
RuleAllow Rule = "ALLOW"
|
||||||
RuleDeny Rule = "DENY"
|
RuleDeny Rule = "DENY"
|
||||||
RuleChallenge Rule = "CHALLENGE"
|
RuleChallenge Rule = "CHALLENGE"
|
||||||
|
RuleWeigh Rule = "WEIGH"
|
||||||
RuleBenchmark Rule = "DEBUG_BENCHMARK"
|
RuleBenchmark Rule = "DEBUG_BENCHMARK"
|
||||||
)
|
)
|
||||||
|
|
||||||
@@ -51,15 +52,15 @@ const (
|
|||||||
)
|
)
|
||||||
|
|
||||||
type BotConfig struct {
|
type BotConfig struct {
|
||||||
|
UserAgentRegex *string `json:"user_agent_regex,omitempty"`
|
||||||
|
PathRegex *string `json:"path_regex,omitempty"`
|
||||||
|
HeadersRegex map[string]string `json:"headers_regex,omitempty"`
|
||||||
|
Expression *ExpressionOrList `json:"expression,omitempty"`
|
||||||
|
Challenge *ChallengeRules `json:"challenge,omitempty"`
|
||||||
|
Weight *Weight `json:"weight,omitempty"`
|
||||||
Name string `json:"name"`
|
Name string `json:"name"`
|
||||||
UserAgentRegex *string `json:"user_agent_regex"`
|
Action Rule `json:"action"`
|
||||||
PathRegex *string `json:"path_regex"`
|
RemoteAddr []string `json:"remote_addresses,omitempty"`
|
||||||
HeadersRegex map[string]string `json:"headers_regex"`
|
|
||||||
RemoteAddr []string `json:"remote_addresses"`
|
|
||||||
Expression *ExpressionOrList `json:"expression"`
|
|
||||||
|
|
||||||
Action Rule `json:"action"`
|
|
||||||
Challenge *ChallengeRules `json:"challenge,omitempty"`
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func (b BotConfig) Zero() bool {
|
func (b BotConfig) Zero() bool {
|
||||||
@@ -151,7 +152,7 @@ func (b BotConfig) Valid() error {
|
|||||||
}
|
}
|
||||||
|
|
||||||
switch b.Action {
|
switch b.Action {
|
||||||
case RuleAllow, RuleBenchmark, RuleChallenge, RuleDeny:
|
case RuleAllow, RuleBenchmark, RuleChallenge, RuleDeny, RuleWeigh:
|
||||||
// okay
|
// okay
|
||||||
default:
|
default:
|
||||||
errs = append(errs, fmt.Errorf("%w: %q", ErrUnknownAction, b.Action))
|
errs = append(errs, fmt.Errorf("%w: %q", ErrUnknownAction, b.Action))
|
||||||
@@ -163,6 +164,10 @@ func (b BotConfig) Valid() error {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if b.Action == RuleWeigh && b.Weight == nil {
|
||||||
|
b.Weight = &Weight{Adjust: 5}
|
||||||
|
}
|
||||||
|
|
||||||
if len(errs) != 0 {
|
if len(errs) != 0 {
|
||||||
return fmt.Errorf("config: bot entry for %q is not valid:\n%w", b.Name, errors.Join(errs...))
|
return fmt.Errorf("config: bot entry for %q is not valid:\n%w", b.Name, errors.Join(errs...))
|
||||||
}
|
}
|
||||||
@@ -171,9 +176,9 @@ func (b BotConfig) Valid() error {
|
|||||||
}
|
}
|
||||||
|
|
||||||
type ChallengeRules struct {
|
type ChallengeRules struct {
|
||||||
|
Algorithm Algorithm `json:"algorithm"`
|
||||||
Difficulty int `json:"difficulty"`
|
Difficulty int `json:"difficulty"`
|
||||||
ReportAs int `json:"report_as"`
|
ReportAs int `json:"report_as"`
|
||||||
Algorithm Algorithm `json:"algorithm"`
|
|
||||||
}
|
}
|
||||||
|
|
||||||
var (
|
var (
|
||||||
|
|||||||
@@ -15,9 +15,9 @@ func p[V any](v V) *V { return &v }
|
|||||||
|
|
||||||
func TestBotValid(t *testing.T) {
|
func TestBotValid(t *testing.T) {
|
||||||
var tests = []struct {
|
var tests = []struct {
|
||||||
|
err error
|
||||||
name string
|
name string
|
||||||
bot BotConfig
|
bot BotConfig
|
||||||
err error
|
|
||||||
}{
|
}{
|
||||||
{
|
{
|
||||||
name: "simple user agent",
|
name: "simple user agent",
|
||||||
@@ -182,6 +182,25 @@ func TestBotValid(t *testing.T) {
|
|||||||
},
|
},
|
||||||
err: nil,
|
err: nil,
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
name: "weight rule without weight",
|
||||||
|
bot: BotConfig{
|
||||||
|
Name: "weight-adjust-if-mozilla",
|
||||||
|
Action: RuleWeigh,
|
||||||
|
UserAgentRegex: p("Mozilla"),
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "weight rule with weight adjust",
|
||||||
|
bot: BotConfig{
|
||||||
|
Name: "weight-adjust-if-mozilla",
|
||||||
|
Action: RuleWeigh,
|
||||||
|
UserAgentRegex: p("Mozilla"),
|
||||||
|
Weight: &Weight{
|
||||||
|
Adjust: 5,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
for _, cs := range tests {
|
for _, cs := range tests {
|
||||||
@@ -239,9 +258,9 @@ func TestConfigValidKnownGood(t *testing.T) {
|
|||||||
|
|
||||||
func TestImportStatement(t *testing.T) {
|
func TestImportStatement(t *testing.T) {
|
||||||
type testCase struct {
|
type testCase struct {
|
||||||
|
err error
|
||||||
name string
|
name string
|
||||||
importPath string
|
importPath string
|
||||||
err error
|
|
||||||
}
|
}
|
||||||
|
|
||||||
var tests []testCase
|
var tests []testCase
|
||||||
|
|||||||
@@ -14,8 +14,8 @@ var (
|
|||||||
|
|
||||||
type ExpressionOrList struct {
|
type ExpressionOrList struct {
|
||||||
Expression string `json:"-"`
|
Expression string `json:"-"`
|
||||||
All []string `json:"all"`
|
All []string `json:"all,omitempty"`
|
||||||
Any []string `json:"any"`
|
Any []string `json:"any,omitempty"`
|
||||||
}
|
}
|
||||||
|
|
||||||
func (eol ExpressionOrList) Equal(rhs *ExpressionOrList) bool {
|
func (eol ExpressionOrList) Equal(rhs *ExpressionOrList) bool {
|
||||||
|
|||||||
@@ -8,11 +8,11 @@ import (
|
|||||||
|
|
||||||
func TestExpressionOrListUnmarshal(t *testing.T) {
|
func TestExpressionOrListUnmarshal(t *testing.T) {
|
||||||
for _, tt := range []struct {
|
for _, tt := range []struct {
|
||||||
name string
|
|
||||||
inp string
|
|
||||||
err error
|
err error
|
||||||
validErr error
|
validErr error
|
||||||
result *ExpressionOrList
|
result *ExpressionOrList
|
||||||
|
name string
|
||||||
|
inp string
|
||||||
}{
|
}{
|
||||||
{
|
{
|
||||||
name: "simple",
|
name: "simple",
|
||||||
|
|||||||
6
lib/policy/config/testdata/good/simple-weight.yaml
vendored
Normal file
6
lib/policy/config/testdata/good/simple-weight.yaml
vendored
Normal file
@@ -0,0 +1,6 @@
|
|||||||
|
bots:
|
||||||
|
- name: simple-weight-adjust
|
||||||
|
action: WEIGH
|
||||||
|
user_agent_regex: Mozilla
|
||||||
|
weight:
|
||||||
|
adjust: 5
|
||||||
4
lib/policy/config/testdata/good/weight-no-weight.yaml
vendored
Normal file
4
lib/policy/config/testdata/good/weight-no-weight.yaml
vendored
Normal file
@@ -0,0 +1,4 @@
|
|||||||
|
bots:
|
||||||
|
- name: weight
|
||||||
|
action: WEIGH
|
||||||
|
user_agent_regex: Mozilla
|
||||||
5
lib/policy/config/weight.go
Normal file
5
lib/policy/config/weight.go
Normal file
@@ -0,0 +1,5 @@
|
|||||||
|
package config
|
||||||
|
|
||||||
|
type Weight struct {
|
||||||
|
Adjust int `json:"adjust"`
|
||||||
|
}
|
||||||
@@ -14,11 +14,11 @@ func TestJoin(t *testing.T) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
for _, tt := range []struct {
|
for _, tt := range []struct {
|
||||||
name string
|
|
||||||
clauses []string
|
|
||||||
op JoinOperator
|
|
||||||
err error
|
err error
|
||||||
|
name string
|
||||||
|
op JoinOperator
|
||||||
resultStr string
|
resultStr string
|
||||||
|
clauses []string
|
||||||
}{
|
}{
|
||||||
{
|
{
|
||||||
name: "no-clauses",
|
name: "no-clauses",
|
||||||
|
|||||||
47
lib/policy/passratechecker.go
Normal file
47
lib/policy/passratechecker.go
Normal file
@@ -0,0 +1,47 @@
|
|||||||
|
package policy
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
"net/http"
|
||||||
|
|
||||||
|
"github.com/TecharoHQ/anubis/internal"
|
||||||
|
"github.com/TecharoHQ/anubis/internal/store/valkey"
|
||||||
|
)
|
||||||
|
|
||||||
|
type PassRateChecker struct {
|
||||||
|
store *valkey.Store
|
||||||
|
header string
|
||||||
|
rate float64
|
||||||
|
}
|
||||||
|
|
||||||
|
func NewPassRateChecker(store *valkey.Store, rate float64) Checker {
|
||||||
|
return &PassRateChecker{
|
||||||
|
store: store,
|
||||||
|
rate: rate,
|
||||||
|
header: "User-Agent",
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (prc *PassRateChecker) Hash() string {
|
||||||
|
return internal.SHA256sum(fmt.Sprintf("pass rate checker::%s", prc.header))
|
||||||
|
}
|
||||||
|
|
||||||
|
func (prc *PassRateChecker) Check(r *http.Request) (bool, error) {
|
||||||
|
data, err := prc.store.MultiGetInt(r.Context(), [][]string{
|
||||||
|
{"pass_rate", prc.header, r.Header.Get(prc.header), "pass"},
|
||||||
|
{"pass_rate", prc.header, r.Header.Get(prc.header), "challenges_issued"},
|
||||||
|
{"pass_rate", prc.header, r.Header.Get(prc.header), "fail"},
|
||||||
|
})
|
||||||
|
if err != nil {
|
||||||
|
return false, err
|
||||||
|
}
|
||||||
|
|
||||||
|
passCount, challengeCount, failCount := data[0], data[1], data[2]
|
||||||
|
passRate := float64(passCount-failCount) / float64(challengeCount)
|
||||||
|
|
||||||
|
if passRate >= prc.rate {
|
||||||
|
return true, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
return false, nil
|
||||||
|
}
|
||||||
@@ -116,6 +116,10 @@ func ParseConfig(fin io.Reader, fname string, defaultDifficulty int) (*ParsedCon
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if b.Weight != nil {
|
||||||
|
parsedBot.Weight = b.Weight
|
||||||
|
}
|
||||||
|
|
||||||
parsedBot.Rules = cl
|
parsedBot.Rules = cl
|
||||||
|
|
||||||
result.Bots = append(result.Bots, parsedBot)
|
result.Bots = append(result.Bots, parsedBot)
|
||||||
|
|||||||
744
package-lock.json
generated
744
package-lock.json
generated
File diff suppressed because it is too large
Load Diff
@@ -6,6 +6,8 @@
|
|||||||
"scripts": {
|
"scripts": {
|
||||||
"test": "npm run assets && go test ./...",
|
"test": "npm run assets && go test ./...",
|
||||||
"test:integration": "npm run assets && go test -v ./internal/test",
|
"test:integration": "npm run assets && go test -v ./internal/test",
|
||||||
|
"test:integration:podman": "npm run assets && go test -v ./internal/test --playwright-runner=podman",
|
||||||
|
"test:integration:docker": "npm run assets && go test -v ./internal/test --playwright-runner=docker",
|
||||||
"assets": "go generate ./... && ./web/build.sh && ./xess/build.sh",
|
"assets": "go generate ./... && ./web/build.sh && ./xess/build.sh",
|
||||||
"build": "npm run assets && go build -o ./var/anubis ./cmd/anubis",
|
"build": "npm run assets && go build -o ./var/anubis ./cmd/anubis",
|
||||||
"dev": "npm run assets && go run ./cmd/anubis --use-remote-address",
|
"dev": "npm run assets && go run ./cmd/anubis --use-remote-address",
|
||||||
@@ -16,9 +18,9 @@
|
|||||||
"author": "",
|
"author": "",
|
||||||
"license": "ISC",
|
"license": "ISC",
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"cssnano": "^7.0.6",
|
"cssnano": "^7.0.7",
|
||||||
"cssnano-preset-advanced": "^7.0.6",
|
"cssnano-preset-advanced": "^7.0.7",
|
||||||
"esbuild": "^0.25.3",
|
"esbuild": "^0.25.4",
|
||||||
"playwright": "^1.52.0",
|
"playwright": "^1.52.0",
|
||||||
"postcss-cli": "^11.0.1",
|
"postcss-cli": "^11.0.1",
|
||||||
"postcss-import": "^16.1.0",
|
"postcss-import": "^16.1.0",
|
||||||
|
|||||||
@@ -1,9 +1,28 @@
|
|||||||
#!/bin/sh
|
#!/bin/sh
|
||||||
|
|
||||||
# PROVIDE: anubis
|
# PROVIDE: anubis
|
||||||
# REQUIRE: NETWORKING
|
# REQUIRE: DAEMON NETWORKING
|
||||||
# KEYWORD: shutdown
|
# KEYWORD: shutdown
|
||||||
|
|
||||||
|
# Add the following lines to /etc/rc.conf.local or /etc/rc.conf to enable anubis:
|
||||||
|
# anubis_enable (bool): Set to "NO" by default.
|
||||||
|
# Set it to "YES" to enable anubis.
|
||||||
|
# anubis_user (user): Set to "www" by default.
|
||||||
|
# User to run anubis as.
|
||||||
|
# anubis_group (group): Set to "www" by default.
|
||||||
|
# Group to run anubis as.
|
||||||
|
# anubis_bin (str): Set to "/usr/local/bin/anubis" by default.
|
||||||
|
# Location of the anubis binary
|
||||||
|
# anubis_args (str): Set to "" by default.
|
||||||
|
# Extra flags passed to anubis.
|
||||||
|
# anubis_env (str): Set to "" by default.
|
||||||
|
# List of environment variables to be set before starting..
|
||||||
|
# anubis_env_file (str): Set to "/etc/anubis.env" by default.
|
||||||
|
# Location of a file containing environment variables.
|
||||||
|
#
|
||||||
|
# Closely follows the init script from https://cgit.freebsd.org/ports/tree/www/go-anubis/files/anubis.in
|
||||||
|
# with a couple of adjustments for more flexible environment variable handling
|
||||||
|
|
||||||
. /etc/rc.subr
|
. /etc/rc.subr
|
||||||
|
|
||||||
name=anubis
|
name=anubis
|
||||||
@@ -12,23 +31,41 @@ rcvar=anubis_enable
|
|||||||
load_rc_config ${name}
|
load_rc_config ${name}
|
||||||
|
|
||||||
: ${anubis_enable="NO"}
|
: ${anubis_enable="NO"}
|
||||||
: ${anubis_user="anubis"}
|
: ${anubis_user="www"}
|
||||||
|
: ${anubis_group="www"}
|
||||||
: ${anubis_bin="/usr/local/bin/anubis"}
|
: ${anubis_bin="/usr/local/bin/anubis"}
|
||||||
: ${anubis_environment_file="/etc/anubis.env"}
|
: ${anubis_args=""}
|
||||||
|
: ${anubis_env=""}
|
||||||
|
: ${anubis_env_file="/etc/anubis.env"}
|
||||||
|
|
||||||
|
pidfile=/var/run/${name}.pid
|
||||||
|
daemon_pidfile=/var/run/${name}-daemon.pid
|
||||||
command=/usr/sbin/daemon
|
command=/usr/sbin/daemon
|
||||||
procname=${anubis_bin}
|
procname=${anubis_bin}
|
||||||
pidfile=/var/run/anubis.pid
|
logfile=/var/log/${name}.log
|
||||||
logfile=/var/log/anubis.log
|
command_args="-c -f -R 5 -r -T ${name} -p ${pidfile} -P ${daemon_pidfile} -o ${logfile} ${procname} ${anubis_args}"
|
||||||
command_args="-c -f -p ${pidfile} -o ${logfile} ${procname}"
|
start_precmd=anubis_startprecmd
|
||||||
start_precmd=anubis_precmd
|
stop_postcmd=anubis_stoppostcmd
|
||||||
|
|
||||||
anubis_precmd () {
|
anubis_startprecmd () {
|
||||||
export $(xargs < ${anubis_environment_file})
|
if [ ! -e ${logfile} ]; then
|
||||||
if [ ! -f ${logfile} ]; then
|
install -o ${anubis_user} -g ${anubis_group} /dev/null ${logfile}
|
||||||
install -o anubis /dev/null ${logfile}
|
fi
|
||||||
fi
|
if [ ! -e ${daemon_pidfile} ]; then
|
||||||
install -o anubis /dev/null ${pidfile}
|
install -o ${anubis_user} -g ${anubis_group} /dev/null ${daemon_pidfile}
|
||||||
|
fi
|
||||||
|
if [ ! -e ${pidfile} ]; then
|
||||||
|
install -o ${anubis_user} -g ${anubis_group} /dev/null ${pidfile}
|
||||||
|
fi
|
||||||
}
|
}
|
||||||
|
|
||||||
|
anubis_stoppostcmd() {
|
||||||
|
if [ -f "${daemon_pidfile}" ]; then
|
||||||
|
pids=$( pgrep -F ${daemon_pidfile} 2>&1 )
|
||||||
|
_err=$?
|
||||||
|
[ ${_err} -eq 0 ] && kill -9 ${pids}
|
||||||
|
fi
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
run_rc_command "$1"
|
run_rc_command "$1"
|
||||||
|
|||||||
@@ -12,8 +12,8 @@ func Base(title string, body templ.Component) templ.Component {
|
|||||||
|
|
||||||
func BaseWithChallengeAndOGTags(title string, body templ.Component, challenge string, rules *config.ChallengeRules, ogTags map[string]string) (templ.Component, error) {
|
func BaseWithChallengeAndOGTags(title string, body templ.Component, challenge string, rules *config.ChallengeRules, ogTags map[string]string) (templ.Component, error) {
|
||||||
return base(title, body, struct {
|
return base(title, body, struct {
|
||||||
Challenge string `json:"challenge"`
|
|
||||||
Rules *config.ChallengeRules `json:"rules"`
|
Rules *config.ChallengeRules `json:"rules"`
|
||||||
|
Challenge string `json:"challenge"`
|
||||||
}{
|
}{
|
||||||
Challenge: challenge,
|
Challenge: challenge,
|
||||||
Rules: rules,
|
Rules: rules,
|
||||||
|
|||||||
Reference in New Issue
Block a user