@tktchurch/auth
v0.2.0
Published
Framework-agnostic auth SDK for TKTChurch OAuth/AuthFlow services
Maintainers
Readme
@tktchurch/auth
Framework-agnostic auth SDK for TKTChurch OAuth/AuthFlow services.
- Default production endpoint:
https://prod-auth.tktchurch.com - Works in browser and Node runtimes (requires
fetch) - Pluggable token storage (
memoryby default) - First-class support for AuthFlow endpoints
Install
npm install @tktchurch/authQuick Start
import { createAuthClient } from "@tktchurch/auth";
const auth = createAuthClient({
clientId: "your_client_id",
// Optional:
// clientSecret: "your_client_secret",
// baseUrl: "https://prod-auth.tktchurch.com",
});
const tokens = await auth.token.password({
username: "[email protected]",
password: "your_password",
scope: "openid profile email",
});
console.log(tokens.accessToken);Framework-Agnostic Usage
Vanilla JavaScript (Browser)
import { createAuthClient, createLocalStorageTokenStorage } from "@tktchurch/auth";
const auth = createAuthClient({
clientId: "web_client",
storage: createLocalStorageTokenStorage(),
});
await auth.token.password({
username: "[email protected]",
password: "secret",
});Next.js / Server Route
import { createAuthClient } from "@tktchurch/auth";
const auth = createAuthClient({
clientId: process.env.TKT_CLIENT_ID!,
clientSecret: process.env.TKT_CLIENT_SECRET!,
});
export async function GET() {
const me = await auth.user.me();
return Response.json(me);
}Framework Examples (Best Practices)
Production-oriented examples are available in:
They follow server-first patterns:
clientSecretremains server-only.- Refresh token is stored in
HttpOnlycookie. - Refresh token rotation is performed on every refresh call.
- Logout revokes refresh token and clears cookie.
Nuxt Module (@tktchurch/auth/nuxt)
Register the module in nuxt.config.ts:
export default defineNuxtConfig({
modules: ["@tktchurch/auth/nuxt"],
tktAuth: {
baseUrl: process.env.TKT_AUTH_BASE_URL ?? "https://prod-auth.tktchurch.com",
clientId: process.env.TKT_CLIENT_ID,
clientSecret: process.env.TKT_CLIENT_SECRET,
autoRefresh: false,
refreshCookieName: "tkt_refresh_token",
},
});Then use provided imports:
const auth = createTktServerAuthClient();
const appAuth = useTktAuth();
const refreshCookieName = useTktRefreshCookieName();AuthFlow Example
const init = await auth.flow.initAuthentication({
username: "[email protected]",
});
let status = await auth.flow.executeStep({
sessionId: init.sessionId,
stepId: init.currentStep.stepId,
credential: {
username: "[email protected]",
password: "secret",
},
});
while (status.status === "in_progress") {
// Render UI for status.nextStep and collect credentials for that step.
status = await auth.flow.executeStep({
sessionId: status.sessionId,
stepId: status.nextStep.stepId,
credential: {},
});
}
// status.status === "complete"
console.log(status.accessToken);Token Storage Adapters
Memory (default)
import { createAuthClient, createMemoryTokenStorage } from "@tktchurch/auth";
const auth = createAuthClient({
clientId: "client_id",
storage: createMemoryTokenStorage(),
});Local Storage (browser)
import { createAuthClient, createLocalStorageTokenStorage } from "@tktchurch/auth";
const auth = createAuthClient({
clientId: "client_id",
storage: createLocalStorageTokenStorage({
key: "my-app-auth",
}),
});Error Handling
import { AuthError, MFARequiredAuthError } from "@tktchurch/auth";
try {
await auth.token.password({
username: "[email protected]",
password: "secret",
});
} catch (error) {
if (error instanceof MFARequiredAuthError) {
console.log("MFA required:", error.mfaMethods);
} else if (error instanceof AuthError) {
console.log(error.code, error.message, error.status);
} else {
throw error;
}
}Authenticated Fetch
fetchWithAuth adds the bearer token automatically and retries once on 401 using refresh token when possible.
const response = await auth.fetchWithAuth("/api/v1/users/me");
if (!response.ok) {
// handle response
}Release and Publish
- Changelog:
CHANGELOG.md - Publishing guide:
PUBLISHING.md
GitHub Packages (private, tktchurch scope) is configured via:
- Script:
bun run publish:github - Workflow:
.github/workflows/publish-github-packages.yml - Auth token:
NODE_AUTH_TOKEN(GITHUB_TOKENin workflow)
npmjs (public) publishing is also configured via:
- Script:
bun run publish:npmjs - Workflow:
.github/workflows/publish-npmjs.yml - Auth: npm trusted publishing (OIDC, no
NPM_TOKENsecret)
