The @harperfast/oauth plugin provides OAuth 2.0 and OpenID Connect (OIDC) authentication for Harper applications.
npm install @harperfast/oauthAdd the plugin to your Harper application's config.yaml:
'@harperfast/oauth':
package: '@harperfast/oauth'
redirectUri: ${OAUTH_REDIRECT_URI}
providers:
github:
clientId: ${OAUTH_GITHUB_CLIENT_ID}
clientSecret: ${OAUTH_GITHUB_CLIENT_SECRET}redirectUri is your app's public origin plus /oauth/callback — the plugin appends the provider name (/oauth/github/callback) when it talks to the provider. It is required; there is no localhost default, so the plugin fails to start with a configuration error if it's missing. For the local walkthrough below, set it explicitly to http://localhost:9926/oauth/callback; on any deployed app, set it to your public origin. See Understanding Redirects.
For local development, export variables in your terminal session:
export OAUTH_GITHUB_CLIENT_ID="your_github_client_id"
export OAUTH_GITHUB_CLIENT_SECRET="your_github_client_secret"
export OAUTH_REDIRECT_URI="http://localhost:9926/oauth/callback" # local dev value — change to your public origin once deployedNote: These
exportcommands are for local development only. You can also use a.envfile withdotenv-clifor local dev — just don't commit it to source control.For Harper Fabric deployments, your app-root
.envis deployed alongside your component, so the same.envyou use locally works in production — see the Harper Fabric documentation for managing runtime environment variables.
If you need to provision users or customize the authentication flow, register hooks in your resources.js:
import { registerHooks } from '@harperfast/oauth';
registerHooks({
onLogin: async (oauthUser, tokenResponse, session, request, provider) => {
// Find or create user
let user;
for await (const u of tables.User.search([{ attribute: 'email', value: oauthUser.email }])) {
user = u;
break;
}
if (!user) {
user = await tables.User.create({ email: oauthUser.email, name: oauthUser.name });
}
return { user: String(user.id) };
},
});See Lifecycle Hooks for complete details.
Security: returning
{ user }is authoritative and bypasses the built-in account-adoption gate. This example is illustrative — before adopting an existing account, confirm the identity (bind to a stable provider identity such asoauthUser.providerUserId, or use a confirmation flow) rather than resolving by email alone;oauthUser.emailVerifiedis not proof of an authenticated source. See onLogin.
npm startNavigate to:
http://localhost:9926/oauth/github/login
The login route is a redirect, so you can confirm what the plugin actually sends the provider without completing a login:
curl -sS -D - -o /dev/null https://your-domain/oauth/github/login | grep -i '^location'In the Location header, check that redirect_uri is your public origin (not localhost) and that client_id is a real value (not an unexpanded %24%7BOAUTH_...%7D, which means the environment variable never reached the deployment). See Common Issues.
The OAuth plugin includes built-in templates for:
- GitHub - OAuth 2.0
- Google - OIDC
- Azure AD - OIDC
- Auth0 - OIDC
- Okta - OIDC
- Custom - Generic OIDC provider
Important: Built-in providers are templates only. None are active until you configure them with
clientId,clientSecret, and other required settings. The presence of provider code does not enable authentication or create security exposure.