Patrick's dev notes - PatrickF1/GraceTunes GitHub Wiki

Replacing Unicorn with Puma

Evaluating thread safety

Puma workers are threads rather than processes so we have to deal with thread safety. Potential problem spots: class variables (they are prefixed with @@), class methods (def self.method), global variables ($global_var), and instance methods where the instance lives on past a single web request.

Conclusion: all the code is thread safe!

Exploring the session cookie store

Learning about sessions

Decrypting a local _GraceTunes_session cookie in rails console

def verify_and_decrypt_session_cookie(cookie, secret_key_base = Rails.application.secret_key_base)
  config = Rails.application.config
  cookie = CGI::unescape(cookie)
  salt   = config.action_dispatch.authenticated_encrypted_cookie_salt
  encrypted_cookie_cipher = config.action_dispatch.encrypted_cookie_cipher || 'aes-256-gcm'
  serializer = ActiveSupport::MessageEncryptor::NullSerializer

  key_generator = ActiveSupport::KeyGenerator.new(secret_key_base, iterations: 1000)
  key_len = ActiveSupport::MessageEncryptor.key_len(encrypted_cookie_cipher)
  secret = key_generator.generate_key(salt, key_len)
  encryptor = ActiveSupport::MessageEncryptor.new(secret, cipher: encrypted_cookie_cipher, serializer: serializer)

  session_key = config.session_options[:key].freeze
  encryptor.decrypt_and_verify(cookie, purpose: "cookie.#{session_key}")
end
=> :verify_and_decrypt_session_cookie
verify_and_decrypt_session_cookie('Sp9vfigwKc534EHjUFVpfMAJvyADLCu4TrDzrDLR5KU%2BMnAhpqCQZRrouMmc6iLtDwj47LqWlddTXQgxayQFlOubjoRK1JtDoW8kCthiZDWBp%2BCDYVfIipPF4SGMaLpX8NZ7MhBVZCUYjTACGIW%2FHOmOH3f0pjVcFjrDR9tl%2BgDGZD7qNor0HmWmzu6PcLtoQ8zIJBNWKKMrOfW7Dy9T7h8mhHq
VAX7ptyTITUpVte%2BQn9hxZJhCqGjo4qL2Z4YcgUeqSPUNKF8HEv3VEsCAzSZfCF6RCL3PqVwfWMAnQ4DnnlrLKM7owoTknmZAF84326UCf6B%2BcwmQS0Os4p3k7TqCznD5hmE6AZyYpuqs9I51nvPXtLzvswV93mpm1ReB%2F9QxRKI%3D--JybhuWBnWpxnuEHA--5g%2BHgLzbirEMkTpqm77OVQ%3D%3D')
=> "{\"session_id\":\"42193dc27a12fca399509e6b6bb29751\",\"_csrf_token\":\"EIqxBDqpUX1Bxmig1WXekbCExnhq4LP5D1JDYfoI8tA\",\"user_email\":\"[email protected]\"}"

How does session cookie expiration work since the cookie doesn't contain a timestamp?

The session ID is generated using SecureRandom.hex which generates a random hex string

Setting up Heroku custom domains

  • How do custom domains work in DNS terms? Heroku sets up a DNS target that provides the A records (which has the actual IP addresses) and and then you configure your domain to alias a subdomain to that DNS target using a CNAME record.
  • Why didn't the custom domain work until I enabled automated SSL certs? because the Rails app had config.force_ssl = true, which redirected it to https port 443 and without certs, there was no point in Rails listening on that port.
  • After setting config.force_ssl = false, how come the http page would still automatically redirect to https? Because by that point, Chrome's security features had cached that the domain uses https and automatically redirects to https. Deleting that cache HTTPS cache entry worked. https://superuser.com/questions/565409/how-to-stop-an-automatic-redirect-from-http-to-https-in-chrome
  • The Heroku DNS Target (e.g. vast-raccoon-s1vn7089sg8wubmhaeqmak9g.herokudns.com) is what is called the canonical name, right? yes
  • How come I can't load the Heroku DNS targets in my browser? Quoting https://help.heroku.com/3EUIOIVB/why-can-t-i-access-herokudns-com-cname-endpoints-in-my-browser
herokudns.com endpoints are not directly browsable and are only to be used as CNAME targets for DNS. 
The Heroku routing layer uses the Host header from the client to ensure the correct application responds to a request - 
this needs to be set to the value of your custom domain (if you have one set up) to route to the correct application. 
As a result, you cannot access your application by visiting the herokudns.com address directly.
dig gracetunes.acts2.network

; <<>> DiG 9.10.6 <<>> gracetunes.acts2.network
;; global options: +cmd
;; Got answer:
;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 10088
;; flags: qr rd ra ad; QUERY: 1, ANSWER: 5, AUTHORITY: 0, ADDITIONAL: 1

;; OPT PSEUDOSECTION:
; EDNS: version: 0, flags:; udp: 1232
;; QUESTION SECTION:
;gracetunes.acts2.network.      IN      A

;; ANSWER SECTION:
gracetunes.acts2.network. 172794 IN     CNAME   vast-raccoon-s1vn7089sg8wubmhaeqmak9g.herokudns.com.
vast-raccoon-s1vn7089sg8wubmhaeqmak9g.herokudns.com. 4 IN A 18.205.36.100
vast-raccoon-s1vn7089sg8wubmhaeqmak9g.herokudns.com. 4 IN A 52.204.242.176
vast-raccoon-s1vn7089sg8wubmhaeqmak9g.herokudns.com. 4 IN A 54.157.58.70
vast-raccoon-s1vn7089sg8wubmhaeqmak9g.herokudns.com. 4 IN A 54.162.128.250

;; Query time: 71 msec
;; SERVER: 100.100.100.100#53(100.100.100.100)
;; WHEN: Wed Nov 15 10:41:10 PST 2023
;; MSG SIZE  rcvd: 182
  • how do I see how long the TTL on the cached DNS records? It's the number in the second column in the dig output, which is in seconds
  • how do I see how the steps the DNS resolver takes? dig +trace domain.name
  • why don't NS records contain the IP addresses of the name server? So that if the IP of the name server changes, the NS admin only need to update one DNS record, and it doesn't affect the users of the NS at all. But yes, it does require the users to do an extra lookup. https://superuser.com/questions/64255/why-are-domain-names-rather-than-ip-addresses-used-in-name-server-records