---
tags:
  - service
  - josiedot
  - irc-now
domain: my.irc.now
status: active
stack:
  - Rust
  - Axum
  - Keycloak OIDC
  - PostgreSQL
auth: Keycloak
---
# irc.now Account Portal (my.irc.now)

Account management portal for irc.now users. Handles authentication, bouncer provisioning, and billing.

## URLs
- https://my.irc.now

## Stack
- Rust (Axum 0.8, openid 0.23, tower-sessions 0.15, askama 0.15)
- PostgreSQL via CNPG (accounts-db)
- kube.rs 3.0 for SojuBouncer CR management
- Stripe (async-stripe 0.41) for billing webhooks

## Auth
Keycloak OIDC via `irc-now` realm, client `account-portal`.
- Login: /auth/login -> Keycloak -> /auth/callback
- Logout: /auth/logout -> Keycloak end-session
- Session: tower-sessions MemoryStore

## Routes
- /auth/login, /auth/callback, /auth/logout
- /dashboard
- /bouncers, /bouncers/create, /bouncers/:name/delete
- /billing, /billing/webhook
- /migrate (GET form, POST import)
- /profile, /profile/update

## Deployment
- OCP namespace: irc-josie-cloud
- ServiceAccount: web-api (RBAC for sojubouncers CRUD, secrets get)
- Build: `oc start-build web-api --from-archive` (rust:1.88 -> ubi9-minimal)
- TLS: cert-manager Certificate CR -> externalCertificate on Route
- Certificate: `my-irc-now-cert` / secret `my-irc-now-tls`
- Env from secrets: accounts-db-app, oidc-account-portal, stripe-keys

## Source
- Repo: ~/development/irc-now
- Crate: `crates/web-api/`

## Profile
- Display name, email with Keycloak sync
- Content settings: auto-expire toggle (pro only, default on, 90-day expiry)
- Keycloak attribute sync: plan + content_expires pushed to user attributes on login, profile save, and Stripe webhook events
- Synced attributes available as ID token claims for txt/pics

## IRCCloud Migration
- `/migrate` imports IRC connections from IRCCloud into a user's soju bouncer
- Authenticates with IRCCloud API (formtoken + login), streams initial state
- Extracts servers (makeserver) and channels (makebuffer) from the event stream
- Auto-creates bouncer if user doesn't have one, waits for DB provisioning
- Inserts networks + channels into soju tenant DB, adds default irc.now upstream
- Credentials used once for fetch, not stored
- Source: `src/irccloud.rs` (API client), `src/routes/migrate.rs` (handlers)

## Related
- [[irc-now-landing]]
- [[irc-now-keycloak]]
