Skip to content

Add ChulaSSO 2.0 login (uni-gated)#1

Merged
RawSalmon69 merged 2 commits into
mainfrom
feat/chulasso-auth
Jun 25, 2026
Merged

Add ChulaSSO 2.0 login (uni-gated)#1
RawSalmon69 merged 2 commits into
mainfrom
feat/chulasso-auth

Conversation

@RawSalmon69

Copy link
Copy Markdown
Member

What

Adds ChulaSSO 2.0 authentication so login can be gated to Chulalongkorn University accounts.

ChulaSSO is a custom ticket flow, not OIDC (/login?ticket=POST /serviceValidation with DeeAppId/DeeAppSecret/DeeTicket → JSON profile), so Kutt's built-in OIDC can't use it. This is a native integration modelled on the existing OIDC handler.

Flow

  • GET /login/chulasso/start → redirect browser to {CHULASSO_BASE}/login?service={site}/login/chulasso&app_id=…
  • GET /login/chulasso → validate the ticket server-side, then find-or-create a verified user by email and issue the normal Kutt session cookie.
  • Optional CHULASSO_ALLOWED_ROLES (e.g. student,faculty) — empty = any authenticated Chula account.
  • "Login with ChulaSSO" button on the login page; login_disabled now exempts ChulaSSO.

Config (new env, see .example.env)

CHULASSO_ENABLED, CHULASSO_BASE, CHULASSO_APP_ID, CHULASSO_APP_SECRET, CHULASSO_ALLOWED_ROLES, CHULASSO_SERVICE_NAME.

Register https://chula.me/ (and https://link.sgcu.in.th/) as allowed Service URL prefixes in the ChulaSSO app; callback is {DEFAULT_DOMAIN}/login/chulasso.

Tests

node server/handlers/chulasso.util.test.js — pure role-gate logic (empty=allow-all, intersection, case/whitespace). Passing.

CI

Adds .github/workflows/ghcr-isd.yaml → builds/pushes ghcr.io/isd-sgcu/kutt. Removes the 3 upstream Docker Hub workflows (wrong registry for this fork). Enable Actions on this fork for it to run.

Not in this PR (deploy-time)

  • Deploy only once the ChulaSSO app is approved and chula.me is Active in Cloudflare.
  • Infra repo: set the Kutt image to ghcr.io/isd-sgcu/kutt, DEFAULT_DOMAIN=chula.me, CHULASSO_ENABLED=true, DISALLOW_LOGIN_FORM=true, anon off; seal CHULASSO_APP_SECRET.
  • UI rebrand (logo/colours via custom/, SITE_NAME) — follow-up.

🤖 Generated with Claude Code

bankworached and others added 2 commits June 25, 2026 16:20
ChulaSSO is Chulalongkorn University's SSO — a custom ticket flow, NOT OIDC,
so Kutt's built-in OIDC can't talk to it. This adds a native integration:

- GET /login/chulasso/start -> redirect to ChulaSSO with our callback as `service`
- GET /login/chulasso       -> validate the returned ticket via
  POST /serviceValidation (DeeAppId/DeeAppSecret/DeeTicket), then find-or-create
  a verified user and issue the Kutt session (mirrors the OIDC handler).
- Optional CHULASSO_ALLOWED_ROLES gate (e.g. student,faculty); empty = any Chula account.
- "Login with ChulaSSO" button on the login page; login_disabled exempts ChulaSSO.
- New CHULASSO_* env, documented in .example.env. Pure role-check helper + unit test.

CI: build/push ghcr.io/isd-sgcu/kutt; drop the upstream Docker Hub workflows.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
…nk, logo)

Adds custom/ overrides: dark :root palette + ISD pink primary, Space Grotesk +
Anuphan fonts (Google Fonts), dark form fields/tables/modals, ISD logo + header
override. Matches the isd.sgcu.in.th visual identity.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
@RawSalmon69 RawSalmon69 merged commit acc6ec7 into main Jun 25, 2026
1 check passed
RawSalmon69 added a commit that referenced this pull request Jun 25, 2026
* feat(auth): add ChulaSSO 2.0 login (uni-gated)

ChulaSSO is Chulalongkorn University's SSO — a custom ticket flow, NOT OIDC,
so Kutt's built-in OIDC can't talk to it. This adds a native integration:

- GET /login/chulasso/start -> redirect to ChulaSSO with our callback as `service`
- GET /login/chulasso       -> validate the returned ticket via
  POST /serviceValidation (DeeAppId/DeeAppSecret/DeeTicket), then find-or-create
  a verified user and issue the Kutt session (mirrors the OIDC handler).
- Optional CHULASSO_ALLOWED_ROLES gate (e.g. student,faculty); empty = any Chula account.
- "Login with ChulaSSO" button on the login page; login_disabled exempts ChulaSSO.
- New CHULASSO_* env, documented in .example.env. Pure role-check helper + unit test.

CI: build/push ghcr.io/isd-sgcu/kutt; drop the upstream Docker Hub workflows.


* feat(ui): SGCU/ISD brand theme (dark, Space Grotesk + Anuphan, ISD pink, logo)

Adds custom/ overrides: dark :root palette + ISD pink primary, Space Grotesk +
Anuphan fonts (Google Fonts), dark form fields/tables/modals, ISD logo + header
override. Matches the isd.sgcu.in.th visual identity.


---------

Co-authored-by: RawSalmon69 <worached.ink@dappmaker.co.th>
Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
RawSalmon69 added a commit that referenced this pull request Jun 25, 2026
* feat(auth): add ChulaSSO 2.0 login (uni-gated)

ChulaSSO is Chulalongkorn University's SSO — a custom ticket flow, NOT OIDC,
so Kutt's built-in OIDC can't talk to it. This adds a native integration:

- GET /login/chulasso/start -> redirect to ChulaSSO with our callback as `service`
- GET /login/chulasso       -> validate the returned ticket via
  POST /serviceValidation (DeeAppId/DeeAppSecret/DeeTicket), then find-or-create
  a verified user and issue the Kutt session (mirrors the OIDC handler).
- Optional CHULASSO_ALLOWED_ROLES gate (e.g. student,faculty); empty = any Chula account.
- "Login with ChulaSSO" button on the login page; login_disabled exempts ChulaSSO.
- New CHULASSO_* env, documented in .example.env. Pure role-check helper + unit test.

CI: build/push ghcr.io/isd-sgcu/kutt; drop the upstream Docker Hub workflows.


* feat(ui): SGCU/ISD brand theme (dark, Space Grotesk + Anuphan, ISD pink, logo)

Adds custom/ overrides: dark :root palette + ISD pink primary, Space Grotesk +
Anuphan fonts (Google Fonts), dark form fields/tables/modals, ISD logo + header
override. Matches the isd.sgcu.in.th visual identity.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants