commit 1e4ab6d2a86a556879d4c29a8c23a79bf12ab430 from: Anton Kasimov date: Fri Aug 21 17:27:39 2026 UTC Шаблон security.txt commit - 4c51bfe09887df95a164fbb4e3e87fe5ac5631ba commit + 1e4ab6d2a86a556879d4c29a8c23a79bf12ab430 blob - /dev/null blob + d323440cdd3a6bc1c0c33893d31a252f44c08634 (mode 644) --- /dev/null +++ layouts/_partials/security-txt.html @@ -0,0 +1,170 @@ +{{- $page := . -}} +{{- $result := resources.FromString ".well-known/security.txt" "" -}} + +{{- if not $page -}} + + {{- errorf "security.txt: security page not found, not published, or expired" -}} + +{{- else -}} + + {{- $params := $page.Params.security -}} + {{- $valid := true -}} + + {{- if not $params -}} + {{- errorf "security.txt: page %q must define params.security" $page.Path -}} + {{- $valid = false -}} + {{- end -}} + + {{- if $page.ExpiryDate.IsZero -}} + {{- errorf "security.txt: page %q must define expiryDate" $page.Path -}} + {{- $valid = false -}} + {{- else if not ($page.ExpiryDate.After now) -}} + {{- errorf + "security.txt: page %q expired on %s" + $page.Path + ($page.ExpiryDate.Format "2006-01-02") + -}} + {{- $valid = false -}} + {{- end -}} + + {{- if and $params (not $params.contact) -}} + {{- errorf "security.txt: page %q must define params.security.contact" $page.Path -}} + {{- $valid = false -}} + {{- end -}} + + + {{- if $valid -}} + + {{- $lines := slice -}} + + {{/* + URI fields. + + Relative values such as /vacancy/ are interpreted as Hugo pages. + Absolute URIs such as mailto:, tel:, https:, openpgp4fpr:, etc. + are passed through unchanged. + */}} + + {{- $fields := slice + (dict "name" "Contact" "values" $params.contact) + (dict "name" "Encryption" "values" $params.encryption) + (dict "name" "Acknowledgments" "values" $params.acknowledgments) + (dict "name" "Policy" "values" ($params.policy | default $page.RelPermalink)) + (dict "name" "Hiring" "values" $params.hiring) + -}} + + {{- range $field := $fields -}} + + {{- with $field.values -}} + + {{- $values := . -}} + + {{- if not (reflect.IsSlice $values) -}} + {{- $values = slice $values -}} + {{- end -}} + + {{- range $values -}} + + {{- $value := printf "%v" . -}} + {{- $url := urls.Parse $value -}} + + {{- if not $url.IsAbs -}} + + {{- $target := $page -}} + + {{- with $url.Path -}} + {{- $target = $page.Site.GetPage . -}} + {{- end -}} + + {{- if not $target -}} + + {{- errorf + "security.txt: %s references page %q which does not exist, is not published, or has expired" + $field.name + $value + -}} + + {{- else -}} + + {{- if and + (not $target.ExpiryDate.IsZero) + (not ($target.ExpiryDate.After now)) + -}} + {{- errorf + "security.txt: %s references expired page %q" + $field.name + $value + -}} + {{- end -}} + + {{- $value = $target.Permalink -}} + + {{- with $url.RawQuery -}} + {{- $value = printf "%s?%s" $value . -}} + {{- end -}} + + {{- with $url.Fragment -}} + {{- $value = printf "%s#%s" $value . -}} + {{- end -}} + + {{- end -}} + + {{- end -}} + + {{- $lines = $lines | append (printf + "%s: %s" + $field.name + $value + ) -}} + + {{- end -}} + + {{- end -}} + + {{- end -}} + + + {{/* Expires */}} + + {{- $lines = $lines | append (printf + "Expires: %s" + ($page.ExpiryDate.UTC.Format "2006-01-02T15:04:05Z") + ) -}} + + + {{/* Preferred-Languages */}} + + {{- with $params.preferred_languages -}} + + {{- $languages := . -}} + + {{- if not (reflect.IsSlice $languages) -}} + {{- $languages = slice $languages -}} + {{- end -}} + + {{- $lines = $lines | append (printf + "Preferred-Languages: %s" + (delimit $languages ", ") + ) -}} + + {{- end -}} + + + {{/* Canonical */}} + + {{- $lines = $lines | append (printf + "Canonical: %s" + ("/.well-known/security.txt" | absURL) + ) -}} + + + {{- $result = resources.FromString + ".well-known/security.txt" + (printf "%s\n" (delimit $lines "\n")) + -}} + + {{- end -}} + +{{- end -}} + +{{- return $result -}}