Other stacks
Next.js, WordPress, apps without a server (SPA), mobile apps, and other libraries.
Any OpenID Connect library works as long as it supports discovery, Authorization Code with PKCE, and ID token checks through JWKS. Point it at the issuer https://accounts.society-ai.org and follow the rules below.
General settings
| Issuer / authority | https://accounts.society-ai.org |
| Response type | code (implicit flow is not allowed) |
| PKCE | S256, required |
| Scope | openid plus what the admin approved, for example openid profile email membership |
| How the secret is sent | client_secret_basic (HTTP Basic). Apps without a server: none |
| Member identity | The sub claim |
| Signing algorithm | RS256 |
Next.js (Auth.js v5)
// auth.ts
import NextAuth from "next-auth";
export const { handlers, auth, signIn, signOut } = NextAuth({
providers: [
{
id: "society-ai",
name: "Society AI",
type: "oidc",
issuer: "https://accounts.society-ai.org",
clientId: process.env.SAI_SSO_CLIENT_ID,
clientSecret: process.env.SAI_SSO_CLIENT_SECRET,
checks: ["pkce", "state"],
authorization: { params: { scope: "openid profile email membership" } },
},
],
});
Callback URL to register: https://<subdomain>.society-ai.org/api/auth/callback/society-ai. Auth.js has no back-channel logout yet, so add your own route handler that follows the rules in the API reference.
WordPress
Use the OpenID Connect Generic plugin with these settings:
| Login Type | Auto Login (SSO) |
| Client ID / Client Secret | from the admin |
| OpenID Scope | openid profile email |
| Login Endpoint URL | https://accounts.society-ai.org/oauth2/auth |
| Userinfo Endpoint URL | https://accounts.society-ai.org/userinfo |
| Token Validation Endpoint URL | https://accounts.society-ai.org/oauth2/token |
| End Session Endpoint URL | https://accounts.society-ai.org/oauth2/sessions/logout |
| Identity Key | sub |
Callback URL to register: https://<subdomain>.society-ai.org/wp-admin/admin-ajax.php?action=openid-connect-authorize.
Apps without a server (SPA)
Ask for an app of the no server kind. You only get a Client ID, and tokens are swapped straight from the browser with PKCE.
// npm install oidc-client-ts
import { UserManager } from "oidc-client-ts";
export const sai = new UserManager({
authority: "https://accounts.society-ai.org",
client_id: "YOUR_CLIENT_ID", // no secret: this app type does not get one
redirect_uri: "https://app.society-ai.org/callback",
response_type: "code", // PKCE is added automatically
scope: "openid profile email membership",
});
// On the "Masuk" button
export const signIn = () => sai.signinRedirect();
// On /callback
export const finishSignIn = () => sai.signinRedirectCallback();
// On "Keluar"
export const signOut = () => sai.signoutRedirect();
- Refresh tokens (
offline_access) are not available. When the token runs out after 15 minutes, callsigninRedirectagain. Members still signed in to Society AI pass through without a screen. Don't usesigninSilent: it relies on a hidden iframe whose cookies Safari and Chrome block. - If your SPA has its own API, check the access token there through
/userinfo. Don't trust data from the browser as is.
Mobile apps
Use AppAuth (Android, iOS) or flutter_appauth, with the no server app kind.
- Open sign-in in the system browser (Custom Tabs or ASWebAuthenticationSession), not a WebView. That way members already signed in on the browser don't have to sign in again.
- The callback URL must be
httpson asociety-ai.orgsubdomain, connected to the app with App Links (Android) or Universal Links (iOS). Custom schemes such asmyapp://can't be registered yet. - Keep tokens in the Keychain or Keystore.