Cait πŸ¦‡'s Avatar

Cait πŸ¦‡

@gendercoffin

feral

1,071
Followers
314
Following
6,813
Posts
07.08.2023
Joined
Posts Following

Latest posts by Cait πŸ¦‡ @gendercoffin

A selfie of Cait shirtless. She has long blonde hair and crows tarried in her shoulders. She’s looking cheeky

A selfie of Cait shirtless. She has long blonde hair and crows tarried in her shoulders. She’s looking cheeky

Guess what, I feel pretty

11.03.2026 01:06 πŸ‘ 15 πŸ” 0 πŸ’¬ 0 πŸ“Œ 0

I just realized that I don't think I've ever heard my dad tell me, my siblings or my mom that he loves us. Dude is incapable of it

10.03.2026 14:37 πŸ‘ 3 πŸ” 0 πŸ’¬ 0 πŸ“Œ 0

Happy anniversary to @sweetgus.bsky.social for an amazing nine years together πŸ–€

08.03.2026 13:20 πŸ‘ 7 πŸ” 0 πŸ’¬ 2 πŸ“Œ 0

Ohhhh that’s what happened! I thought something was off!

08.03.2026 13:07 πŸ‘ 1 πŸ” 0 πŸ’¬ 1 πŸ“Œ 0

I was also able to do cool stuff like support right-to-left UI for Arabic language users, right out of the box. So yeah, if you're starting a new crossplatform app I definitely recommend learning Dart (it's not too different from TypeScript) and giving Flutter a try

08.03.2026 02:39 πŸ‘ 2 πŸ” 0 πŸ’¬ 1 πŸ“Œ 0

Now instead of doing a Git merge and fixing merge conflicts, I can just run one shell script that creates me Android and iOS app packages I can upload. I'm sure if I wanted to be clever I could automate the upload process too

08.03.2026 02:37 πŸ‘ 0 πŸ” 0 πŸ’¬ 1 πŸ“Œ 0

I was also able to move away from my old approach of creating multiple versions of the app using different Git branches, to creating one unified branch and creating different build flavors that take a set of version-specific configuration files.

08.03.2026 02:36 πŸ‘ 0 πŸ” 0 πŸ’¬ 1 πŸ“Œ 0

I just finished (mostly) a nontrivial science data collection app that had been built in HTML and JavaScript using Angular / Capacitor, completely in Dart using Flutter. I think I might adore Flutter? It makes it so much easier to make a cross-platform app feel like a real app!

08.03.2026 02:34 πŸ‘ 1 πŸ” 0 πŸ’¬ 1 πŸ“Œ 0

If I wanted to I could do this properly with Cloudflare I could do that, but I have nasty feelings about Cloudflare, I don't have money for Cloudflare, and this was something I could knock out in 20 minutes

07.03.2026 03:30 πŸ‘ 2 πŸ” 0 πŸ’¬ 0 πŸ“Œ 0
A wall of green text on a black screen showing a ton of malicious requests to commonly used configuration secret files that could let someone hack my app

A wall of green text on a black screen showing a ton of malicious requests to commonly used configuration secret files that could let someone hack my app

@Injectable()
export class HoneypotMiddleware implements NestMiddleware {
	private readonly logger = new Logger('HoneypotMiddleware');

	private readonly criticalPaths = [
		/\.env/,
		/sendgrid_keys/,
		/sendgrid_config/,
		/secrets\//,
		/\.git\//,
	];
	private readonly suspiciousPaths = [
		/wp-admin/,
		/wp-content/,
		/wp-includes/,
		/\.php$/,
		/backup\//,
	];

	private readonly jail = new Map<string, IPStatus>();
	private readonly BAN_DURATION_MS = 1000 * 60 * 60 * 24;
	private readonly MAX_STRIKES = 3;

	use(req: Request, res: Response, next: NextFunction) {
		const clientIp = this.getIp(req);
		const url = req.originalUrl;

		// 1. Check if IP is currently in jail
		if (this.isJailed(clientIp)) {
			this.logger.warn(`[HTTP] BLOCKED IP: ${clientIp} | Attempted: ${url}`);
			return res.status(403).json({ message: 'Access Denied' });

@Injectable() export class HoneypotMiddleware implements NestMiddleware { private readonly logger = new Logger('HoneypotMiddleware'); private readonly criticalPaths = [ /\.env/, /sendgrid_keys/, /sendgrid_config/, /secrets\//, /\.git\//, ]; private readonly suspiciousPaths = [ /wp-admin/, /wp-content/, /wp-includes/, /\.php$/, /backup\//, ]; private readonly jail = new Map<string, IPStatus>(); private readonly BAN_DURATION_MS = 1000 * 60 * 60 * 24; private readonly MAX_STRIKES = 3; use(req: Request, res: Response, next: NextFunction) { const clientIp = this.getIp(req); const url = req.originalUrl; // 1. Check if IP is currently in jail if (this.isJailed(clientIp)) { this.logger.warn(`[HTTP] BLOCKED IP: ${clientIp} | Attempted: ${url}`); return res.status(403).json({ message: 'Access Denied' });

I got tired of seeing scrapers hit my backend looking for exposed configuration files so I created a NestJS middleware that catches commonly-requested malicious requests and puts the IP address in a jail that prevents them from making any more requests for 24 hours

07.03.2026 03:29 πŸ‘ 3 πŸ” 0 πŸ’¬ 1 πŸ“Œ 0
Tweet

Claude Code wiped our production database with a Terraform command.
It took down the DataTalksClub course platform and 2.5 years of submissions: homework, projects, and leaderboards.
Automated snapshots were gone too.
In the newsletter, I wrote the full timeline + what I changed so this doesn't happen again.
If you use Terraform (or let agents touch infra), this is a good story for you to read.

Tweet Claude Code wiped our production database with a Terraform command. It took down the DataTalksClub course platform and 2.5 years of submissions: homework, projects, and leaderboards. Automated snapshots were gone too. In the newsletter, I wrote the full timeline + what I changed so this doesn't happen again. If you use Terraform (or let agents touch infra), this is a good story for you to read.

Back in my day you needed a senior engineer for this sort of thing

06.03.2026 16:54 πŸ‘ 1903 πŸ” 273 πŸ’¬ 63 πŸ“Œ 123

hi abby!!

04.03.2026 11:36 πŸ‘ 1 πŸ” 0 πŸ’¬ 1 πŸ“Œ 0

One of the great things about Dark Souls is that if it's in the game, Hidetaka Miyazaki probably has a fetish for it. A giantess with huge boobs? A body-hugging iron cage that doubles as an elevator? The man has said he wants to be beaten to death by a giant mushroom. Huge horndog, I love it

03.03.2026 04:16 πŸ‘ 4 πŸ” 0 πŸ’¬ 0 πŸ“Œ 0
WITCHZ - KILLEM
WITCHZ - KILLEM YouTube video by WITCHZ

WITCHZ is so fun!
www.youtube.com/watch?v=aFHK...

03.03.2026 03:03 πŸ‘ 1 πŸ” 0 πŸ’¬ 0 πŸ“Œ 0

Coming up on seven years since I came out at work. Fuck.

01.03.2026 21:28 πŸ‘ 9 πŸ” 0 πŸ’¬ 0 πŸ“Œ 0

If I’m not careful my inner dialogue goes over to β€œna nananana, we’re completely fucked, we’re completely fucked” to the tune of β€œGive it Up” by KC And The Sunshine Band

01.03.2026 21:23 πŸ‘ 4 πŸ” 0 πŸ’¬ 0 πŸ“Œ 0

I can’t wait for shortall season here, that’s a good look

01.03.2026 21:19 πŸ‘ 1 πŸ” 0 πŸ’¬ 1 πŸ“Œ 0

Her husband thought cell towers were carcinogenic and didn’t allow WiFi but he still had a cell phone.

01.03.2026 21:10 πŸ‘ 3 πŸ” 0 πŸ’¬ 0 πŸ“Œ 0

Once upon a time I had a landlord tell me she didn’t like male students from University of Maine because they had β€œtoo much testosterone”.

Oh, Diane

01.03.2026 21:08 πŸ‘ 4 πŸ” 0 πŸ’¬ 1 πŸ“Œ 0

Bad Omens are the Backstreet Boys of metal (and that's OK! I liked the Backstreet Boys)

01.03.2026 19:02 πŸ‘ 1 πŸ” 0 πŸ’¬ 0 πŸ“Œ 0
A screengrab of a website data listing showing a photo of a very doofy cat and some stats from a weather buoy

A screengrab of a website data listing showing a photo of a very doofy cat and some stats from a weather buoy

Test observation

01.03.2026 19:01 πŸ‘ 1 πŸ” 0 πŸ’¬ 0 πŸ“Œ 0
WITCHZ - POSSESSED
WITCHZ - POSSESSED YouTube video by WITCHZ

Can I just say I absolutely love WITCHZ. It's phonk-metal-rap-goth with a tinge of cowboy and all of these elements come together so well

www.youtube.com/watch?v=iQLM...

01.03.2026 18:57 πŸ‘ 0 πŸ” 0 πŸ’¬ 0 πŸ“Œ 0

The script above just handles getting NOAA buoy data, but you get the gist

01.03.2026 18:54 πŸ‘ 1 πŸ” 0 πŸ’¬ 1 πŸ“Œ 0
A screenshot of a data pipeline editor with a code editor. In it the code reads:

name: NOAA Buoy Telemetry Integration
steps:
  - id: buoy_data
    uses: noaa.buoytelemetry
    with:
      lat: "{{observation.location.lat}}"
      lng: "{{observation.location.lng}}"
      radius: 40
      observed: "{{observation.observed}}"
      products:
        - air_pressure
        - air_temperature
        - water_level
        - water_temperature
        - one_minute_water_level
  - id: update_observation_fields
    uses: observation.patch
    with:
      parent_fields:
        - slug: noaa-station-name-2
          value: "{{steps.buoy_data.station_name}}"
        - slug: noaa-station-id-2
          value: "{{steps.buoy_data.station_id}}"
        - slug: noaa-station-coordinates-2
          value: "{{steps.buoy_data.station_id}}"
        - slug: buoy-sample-time-gmt
          value: "{{steps.buoy_data.sample_time}}"
        - slug: buoy-air-pressure-2
          value: "{{steps.buoy_data.air_pressure}}"
        - slug: buoy-air-temperature-2
          value: "{{steps.buoy_data.air_temperature}}"
        - slug: buoy-water-level-2
          value: "{{steps.buoy_data.water_level}}"
        - slug: buoy-1-minute-water-level-2
          value: "{{steps.buoy_data.one_minute_water_level}}"
        - slug: buoy-water-temperature-2
          value: "{{steps.buoy_data.water_temperature}}"
      observation_id: "{{observation.id}}"
    condition: "{{steps.buoy_data.station_id}}"
trigger:
  - observation.created
  - observation.updated

A screenshot of a data pipeline editor with a code editor. In it the code reads: name: NOAA Buoy Telemetry Integration steps: - id: buoy_data uses: noaa.buoytelemetry with: lat: "{{observation.location.lat}}" lng: "{{observation.location.lng}}" radius: 40 observed: "{{observation.observed}}" products: - air_pressure - air_temperature - water_level - water_temperature - one_minute_water_level - id: update_observation_fields uses: observation.patch with: parent_fields: - slug: noaa-station-name-2 value: "{{steps.buoy_data.station_name}}" - slug: noaa-station-id-2 value: "{{steps.buoy_data.station_id}}" - slug: noaa-station-coordinates-2 value: "{{steps.buoy_data.station_id}}" - slug: buoy-sample-time-gmt value: "{{steps.buoy_data.sample_time}}" - slug: buoy-air-pressure-2 value: "{{steps.buoy_data.air_pressure}}" - slug: buoy-air-temperature-2 value: "{{steps.buoy_data.air_temperature}}" - slug: buoy-water-level-2 value: "{{steps.buoy_data.water_level}}" - slug: buoy-1-minute-water-level-2 value: "{{steps.buoy_data.one_minute_water_level}}" - slug: buoy-water-temperature-2 value: "{{steps.buoy_data.water_temperature}}" observation_id: "{{observation.id}}" condition: "{{steps.buoy_data.station_id}}" trigger: - observation.created - observation.updated

I made an automation pipeline system using a Domain-Specific Language that I designed based on YAML that can do cool things when volunteers submit observations, like automatically getting the coordinates from a typed-in address and then fetching the data from the nearest NOAA weather buoy

01.03.2026 18:53 πŸ‘ 3 πŸ” 0 πŸ’¬ 1 πŸ“Œ 0

Urgent: Rent is due TODAY and I'm $150 short. Anything helps.

Cashapp: $cactusgr
PayPal: ask

#mutualaid

Thank you<3

01.03.2026 18:23 πŸ‘ 20 πŸ” 29 πŸ’¬ 0 πŸ“Œ 0

πŸ’ž

01.03.2026 15:07 πŸ‘ 1 πŸ” 0 πŸ’¬ 0 πŸ“Œ 0
Cait and a small cat sitting on a futon. The cat is leaning against her

Cait and a small cat sitting on a futon. The cat is leaning against her

Proof of life (featuring Tuna)

01.03.2026 15:05 πŸ‘ 7 πŸ” 0 πŸ’¬ 1 πŸ“Œ 0

They've been letting this languish in the TCP/IP spec committee for YEARS now >>:(

26.02.2026 01:20 πŸ‘ 1 πŸ” 0 πŸ’¬ 1 πŸ“Œ 0
Video thumbnail

This just popped into my head

26.02.2026 00:59 πŸ‘ 3 πŸ” 0 πŸ’¬ 0 πŸ“Œ 0

I feel like it's a real theme on anything career related. It's not the first time

25.02.2026 20:51 πŸ‘ 1 πŸ” 0 πŸ’¬ 0 πŸ“Œ 0