Skip to content

Instantly share code, notes, and snippets.

View atomkirk's full-sized avatar

Adam Kirk atomkirk

View GitHub Profile
@atomkirk
atomkirk / cloud-files.md
Last active April 8, 2025 12:15
Storing files on S3 with Elixir

I have this abstraction in my application code called a "CloudFile". This is where I store in the database information about files on S3 and it gives me a resource for other resources to own. For example, a user would have an avatar_cloud_file_id. On the front-end, I would load this relationship and display the avatar with user.avatar_cloud_file.download_url

defmodule RL.CloudFile do
  use Ecto.Schema
  import Ecto.Changeset

  @timestamps_opts type: :utc_datetime_usec
@atomkirk
atomkirk / ios-camera.html
Created March 13, 2020 04:49
iOS Safari Camera API
<video id="player" autoplay muted playsinline> </video>
<button id="capture">Capture</button>
<canvas id="canvas" width=320 height=240></canvas>
<script>
const player = document.getElementById('player');
const canvas = document.getElementById('canvas');
const context = canvas.getContext('2d');
const captureButton = document.getElementById('capture');
const constraints = {
@atomkirk
atomkirk / download-zoom-recording.md
Last active March 6, 2025 12:09
Force download a zoom recording
  1. Open dev tools
  2. Search for the <video… tag.
  3. Copy the source URL
  4. Right click on the body tag and click Edit as HTML
  5. Add an a link with the src right inside the body tag like:
<body>
  <a href="url-you-copied">download</a>
  ...
@atomkirk
atomkirk / hide-all-annotations.js
Last active December 28, 2024 15:40
hide all github annotations on a PR
javascript:(function() {document.querySelectorAll('.js-inline-annotations').forEach(function(annotation) {if (annotation.innerText.includes('coverbot')) {annotation.remove();}});})();
@atomkirk
atomkirk / soc2-by-myself.md
Last active August 6, 2024 20:50
I got SOC 2 certified by myself

I got SOC 2 certified by myself

From April 10 to May 2, 2024, I did all the work myself to get SOC 2 Type II certified. I'm now half way through the observation period to get Type II. The observation period is easy, you just have to babysit the controls. Getting to Type I is much harder. It took me somewhere around 100 hours.

image

SOC 2 is a security framework that, for many customers, eliminates the need to have you, as a vendor, fill out a lengthy security questionnaire. The SOC 2 controls and audits ask pretty much all the questions you'd get from a customer's security team. In fact, that is a great way to think about SOC 2. It's essentially a very thorough questionnaire you fill out once, an independent auditor forms an opinion of it in a report, and you share with all your customers.

There are two parts to SOC 2. The initial audit, where an auditor writes a Type I report sharing their opinion of your current setup. Then there's a 3 month observ

@atomkirk
atomkirk / webhooks-receiver.tf
Last active August 5, 2024 19:35
Terraform GCP Cloud Function Source
locals {
function_name = "${var.space}-webhook-receiver"
}
resource "google_pubsub_topic" "webhook_events" {
name = "${var.space}-webhook-events"
message_retention_duration = "432000s"
}
@atomkirk
atomkirk / ecto-url-validation.md
Last active August 4, 2024 03:51
validate url in elixir

Here's an ecto changeset validation for urls:

  @doc """
  validates field is a valid url

  ## Examples
    iex> Ecto.Changeset.cast(%ZB.Account{}, %{"website" => "https://www.zipbooks.com"}, [:website])
    ...> |> Utils.Changeset.validate_url(:website)
    ...> |> Map.get(:valid?)
@atomkirk
atomkirk / stop-all-docker.md
Created February 9, 2021 14:25
Stop all Docker containers

I will often run this command to make sure all my docker containers are stopped and removed before running docker-compose up. Sometimes when you restart your system, old containers will start back up automatically in the background.

docker stop $(docker ps -aq) && docker rm $(docker ps -aq)
@atomkirk
atomkirk / custom_segue.swift
Last active February 26, 2023 15:50
Custom Fade In/Out Segue
import UIKit
// All you do is assign this class to a segue in your storyboard and you're done
class BottomCardSegue: UIStoryboardSegue {
private var selfRetainer: BottomCardSegue? = nil
override func perform() {
destination.transitioningDelegate = self