Skip to content

Instantly share code, notes, and snippets.

@wvengen
Last active January 30, 2025 11:12
Show Gist options
  • Save wvengen/a110cbf07819f2ce7082d4435f6d2034 to your computer and use it in GitHub Desktop.
Save wvengen/a110cbf07819f2ce7082d4435f6d2034 to your computer and use it in GitHub Desktop.
Sign a Hypothesis Via URL
#!/usr/bin/env ruby
#
# Ruby implementation for signing Via URLs (proof of concept)
#
# Useful when SIGNED_URLS_REQUIRED is enabled and VIA_SECRET set.
# See https://github.com/hypothesis/via for more information.
#
require 'blake2b'
require 'jwt'
require 'uri'
# TODO
# - implement strip_token
# - quantize expires to improve caching
# https://github.com/hypothesis/h-vialib/blob/c78981c98001c19c83751b7c68497d672a5f25f3/src/h_vialib/secure/expiry.py#L9
def strip_token(url)
# TODO strip any "via.sec" query parameter from url
url
end
def hash_url_v1(url)
url = strip_token(url)
digest = Blake2b.bytes(url, Blake2b::Key.none, 15)
Base64.strict_encode64(digest.map(&:chr).join)
end
def sign(url, key:, expires:, payload: {})
payload["h"] = hash_url_v1(url)
payload["exp"] = expires.to_i
jwt = JWT.encode(payload, key, "HS256")
uri = URI.parse(url)
query = URI.decode_www_form(uri.query || '') << [ "via.sec", jwt ]
uri.query = URI.encode_www_form(query)
uri.to_s
end
KEY = "not_a_secret" # default Via development secret, don't use this in public!
ARGF.each do |line|
url = line.strip
expires = Time.now + 60 * 60 # 1 hour from now
puts sign(url, key: KEY, expires:)
end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment