Skip to content

Instantly share code, notes, and snippets.

Avatar
🐼
fuzzy logic

Josh Goodall inopinatus

🐼
fuzzy logic
View GitHub Profile
View verify_and_decrypt_session_cookie52.rb
require 'cgi'
require 'active_support'
def verify_and_decrypt_session_cookie(cookie, secret_key_base = Rails.application.secret_key_base)
cookie = CGI::unescape(cookie)
salt = 'authenticated encrypted cookie'
encrypted_cookie_cipher = 'aes-256-gcm'
serializer = ActiveSupport::MessageEncryptor::NullSerializer
key_generator = ActiveSupport::KeyGenerator.new(secret_key_base, iterations: 1000)
@inopinatus
inopinatus / castaway.rb
Created Apr 23, 2021
dangerous polymorphic fun with primary key casts (nsfw)
View castaway.rb
class CastIdsToText < ActiveRecord::Migration[6.0]
def up
add_cast :text, :uuid, function: :inout, context: :implicit
add_cast :text, :bigint, function: :inout, context: :implicit
end
def down
remove_cast :text, :uuid
remove_cast :text, :bigint
end
@inopinatus
inopinatus / uu58.rb
Last active Jan 18, 2021
Convert UUIDs to/from base58
View uu58.rb
module Uu58
# Convert a string UUID to a base58 string representation.
#
# Output will be padded up to 22 digits if necessary.
#
# Behaviour is undefined if passing something other than a 128-bit
# hex string in network order with optional interstitial hyphens.
def self.uuid_to_base58(uuid, alphabet = SecureRandom::BASE58_ALPHABET)
ary = uuid.delete("-").to_i(16).digits(58).reverse
ary.unshift(0) while ary.length < 22
@inopinatus
inopinatus / bouquet-controller.js
Created Jan 8, 2021
Proof-of-concept, using a Stimulus wrapper for IntersectionObserver to drive Turbo lazy-loading via click events, with graceful fallback to plain HTML.
View bouquet-controller.js
import { Controller } from "stimulus"
// Proof of concept for lazy loaded turbo frames
export default class extends Controller {
static targets = ["click", "events", "root"]
static values = {
rootMargin: String,
threshold: Number,
appearEvent: String,
disappearEvent: String
@inopinatus
inopinatus / worry.rb
Last active Jan 8, 2021
Abusing pattern matching as a proc factory and subsequent invocation
View worry.rb
# frozen_string_literal: true
require 'json'
module Proxy
refine Object do
def deconstruct_keys(methods)
methods.to_h { |m| [m, ->(*a) { throw m, public_send(m, *a) }] }
end
end
end
@inopinatus
inopinatus / route-authenticators.rb
Created Dec 22, 2020
Injecting route-specific dependencies to avoid controller duplication.
View route-authenticators.rb
# config/routes.rb
defaults authenticator: UserAuthenticator do
resources :todos
end
scope :api, defaults: { authenticator: APIAuthenticator, format: :json } do
resources :todos
end
# app/lib/user_authenticator.rb
@inopinatus
inopinatus / organisation.rb
Created Dec 14, 2020
Value object that replaced an enum
View organisation.rb
# app/models/organisation.rb
# schema like:
#
# create_table "organisations", id: :uuid, default: -> { "public.gen_random_uuid()" }, force: :cascade do |t|
# t.string "transponder", default: "my_laps", null: false
#
class Organisation < ApplicationRecord
attribute :transponder, TransponderType.new
@inopinatus
inopinatus / resprocketize.diff
Created Aug 27, 2019
Re-enable sprockets handling JS in Rails 6.0
View resprocketize.diff
diff --git a/Gemfile b/Gemfile
index 79cc614..9e03100 100644
--- a/Gemfile
+++ b/Gemfile
@@ -11,6 +11,8 @@ gem 'sqlite3', '~> 1.4'
gem 'puma', '~> 3.11'
# Use SCSS for stylesheets
gem 'sass-rails', '~> 5'
+# Bring back uglifier for sprockets
+gem 'uglifier', '>= 1.3.0'
@inopinatus
inopinatus / application_record.rb
Created Oct 14, 2020
values_at for active record models
View application_record.rb
class ApplicationRecord < ActiveRecord::Base
self.abstract_class = true
unless instance_methods.include?(:values_at)
def values_at(*methods)
methods.flatten.map! { |method| public_send(method) }
end
end
end
@inopinatus
inopinatus / config_objects.rb
Last active Oct 5, 2020
excessively dynamic accessors
View config_objects.rb
class MyConfiguration < BasicObject
def method_missing name, *args
getter = name.end_with?(?=) ? name[0..-2] : name
(class << self; self end).class_eval { attr_accessor getter }
__send__ name, *args
end
end
config = MyConfiguration.new
config.liverpool = 4