A comprehensive Svelte authentication library with WebAuthn/passkey support, designed for whitelabel applications and Flow app projects.
This package is published to GitHub Packages. You'll need to configure your package manager to use the GitHub registry for @thepia
scoped packages.
Using npm:
# Configure registry for @thepia scope
npm config set @thepia:registry https://npm.pkg.github.com
# Set authentication token (required for GitHub Packages)
npm config set //npm.pkg.github.com/:_authToken YOUR_GITHUB_PERSONAL_ACCESS_TOKEN
# Install the package
npm install @thepia/flows-auth
Using pnpm:
# Configure registry in .npmrc file
echo "@thepia:registry=https://npm.pkg.github.com" >> .npmrc
echo "//npm.pkg.github.com/:_authToken=YOUR_GITHUB_PERSONAL_ACCESS_TOKEN" >> .npmrc
# Install the package
pnpm install @thepia/flows-auth
Using yarn:
# Configure registry
yarn config set @thepia:registry https://npm.pkg.github.com
# Install the package (you'll be prompted for authentication)
yarn add @thepia/flows-auth
Note: You need a GitHub Personal Access Token with
read:packages
scope to install from GitHub Packages. Set theNODE_AUTH_TOKEN
environment variable or configure it in your.npmrc
file.
<script>
import { SignInForm, createAuthStore } from '@thepia/flows-auth';
const authConfig = {
apiBaseUrl: 'https://api.yourapp.com',
clientId: 'your-client-id',
domain: 'yourapp.com',
enablePasskeys: true,
enableMagicLinks: true,
branding: {
companyName: 'Your Company',
logoUrl: '/logo.svg',
primaryColor: '#0066cc'
}
};
const auth = createAuthStore(authConfig);
function handleSuccess({ detail }) {
console.log('Signed in:', detail.user);
}
</script>
<SignInForm
config={authConfig}
on:success={handleSuccess}
/>
The main authentication component that handles the complete sign-in flow.
<SignInForm
{config}
showLogo={true}
compact={false}
initialEmail=""
on:success={handleSuccess}
on:error={handleError}
on:stateChange={handleStateChange}
/>
Props:
config
- Authentication configuration objectshowLogo
- Whether to display the company logocompact
- Use compact layout for modals/small spacesinitialEmail
- Pre-fill email fieldclassName
- Additional CSS classesEvents:
success
- User successfully authenticatederror
- Authentication error occurredstateChange
- Authentication step changedThe complete user registration component with WebAuthn passkey support, invitation tokens, and immediate app access.
<AccountCreationForm
{config}
showLogo={true}
compact={false}
initialEmail=""
invitationTokenData={null}
additionalFields={['company', 'phone', 'jobTitle']}
readOnlyFields={[]}
on:appAccess={handleAppAccess}
on:success={handleSuccess}
on:error={handleError}
on:switchToSignIn={handleSwitchToSignIn}
/>
Props:
config
- Authentication configuration objectshowLogo
- Whether to display the company logocompact
- Use compact layout for modals/small spacesinitialEmail
- Pre-fill email fieldinvitationTokenData
- Invitation token data for prefilling fieldsadditionalFields
- Array of additional business fields to showreadOnlyFields
- Array of field names that should be read-onlyclassName
- Additional CSS classesEvents:
appAccess
- User should enter app immediately after registrationsuccess
- User successfully registerederror
- Registration error occurredswitchToSignIn
- User wants to switch to sign-in modestepChange
- Registration step changedYou can also use individual step components for custom flows:
import {
EmailStep,
PasskeyStep,
MagicLinkStep
} from '@thepia/flows-auth/components';
The auth store manages authentication state and provides methods for sign-in/out.
import { createAuthStore } from '@thepia/flows-auth/stores';
const auth = createAuthStore(config);
// Subscribe to auth state
auth.subscribe($auth => {
console.log('Auth state:', $auth.state);
console.log('User:', $auth.user);
});
// Sign in methods
await auth.signIn('[email protected]');
await auth.signInWithPasskey('[email protected]');
await auth.signInWithMagicLink('[email protected]');
// Other methods
await auth.signOut();
await auth.refreshTokens();
const isAuthenticated = auth.isAuthenticated();
const token = auth.getAccessToken();
interface AuthConfig {
// Required
apiBaseUrl: string;
clientId: string;
domain: string;
// Feature flags
enablePasskeys: boolean;
enableMagicLinks: boolean;
// Optional
redirectUri?: string;
branding?: AuthBranding;
}
interface AuthBranding {
companyName: string;
logoUrl?: string;
primaryColor?: string;
secondaryColor?: string;
showPoweredBy?: boolean;
customCSS?: string;
}
The library supports complete visual customization through CSS custom properties:
:root {
/* Brand colors */
--auth-primary-color: #your-brand-color;
--auth-secondary-color: #your-secondary-color;
--auth-accent-color: #your-accent-color;
/* Typography */
--auth-font-family: 'Your Brand Font', sans-serif;
--auth-border-radius: 8px;
/* Spacing */
--auth-padding: 24px;
--auth-gap: 16px;
}
Or use the branding configuration:
const config = {
// ... other config
branding: {
companyName: 'ACME Corp',
logoUrl: '/acme-logo.svg',
primaryColor: '#ff0000',
secondaryColor: '#00ff00',
customCSS: `
.auth-form { border-radius: 0; }
.auth-button { text-transform: uppercase; }
`
}
};
flows-auth is production-ready and correctly interfaces with the thepia.com authentication API.
POST /auth/check-user
- User existence and passkey checkingPOST /auth/webauthn/challenge
- WebAuthn challenge generation POST /auth/webauthn/verify
- Passkey authentication verificationPOST /auth/register
- New user account creationPOST /auth/webauthn/register-options
- Passkey registration optionsPOST /auth/webauthn/register-verify
- Passkey registration verificationCurrently receives placeholder tokens from thepia.com API ("webauthn-verified"
). flows-auth stores and uses these tokens correctly. Will automatically work with real JWT tokens when thepia.com implements them per their documented plan.
See API Integration Status for complete technical details.
The following documents are the single source of truth for their respective topics. When information conflicts between documents, these authorities take precedence:
Document | Authority Over | Status |
---|---|---|
docs/specifications/AccountCreationForm-spec.md |
AccountCreationForm component behavior, events, props | โ Authoritative |
docs/specifications/signInWithPasskey-spec.md |
WebAuthn/passkey authentication flow | โ Authoritative |
docs/SESSION_MANAGEMENT_REQUIREMENTS.md |
Session storage, timeouts, state management | โ Authoritative |
docs/testing/API_CONTRACT_TESTING_POLICY.md |
API integration testing requirements | โ Authoritative |
Document | Authority Over | Status |
---|---|---|
docs/STORAGE_CONFIGURATION.md |
Storage adapters, role-based configuration | โ Authoritative |
docs/INVITATION_TOKEN_IMPLEMENTATION.md |
Invitation token format, validation, flows | โ Authoritative |
docs/privacy/zero-cookie-architecture.md |
Privacy architecture, cookie-free design | โ Authoritative |
Document | Authority Over | Status |
---|---|---|
docs/testing/README.md |
Testing strategy, coverage requirements | โ Authoritative |
docs/testing/thepia-com-api-contracts/ |
API contract specifications | โ Authoritative |
docs/CRITICAL_ISSUES_AND_FIXES.md |
Known issues, root causes, fix status | โ Authoritative |
Document | Authority Over | Status |
---|---|---|
docs/CRITICAL_ISSUES_AND_FIXES.md |
createAccount session saving, doc consolidation plan | โ Authoritative |
docs/BREAKING_CHANGES_CHECKLIST.md |
Breaking change protocols, API compatibility | โ Authoritative |
Document | Authority Over | Status |
---|---|---|
CLAUDE.md |
AI development patterns, common mistakes | โ Authoritative |
docs/development/api-server-architecture.md |
Server-side implementation requirements | โ Authoritative |
docs/components/AccountCreationForm.md |
Component usage examples, integration patterns | โ Authoritative |
Document | Status | Migration Path |
---|---|---|
docs/testing/IMPLEMENTATION_CHECKLIST.md |
โ Archived | docs/archive/IMPLEMENTATION_CHECKLIST.md |
docs/testing/FINDINGS_AND_RECOMMENDATIONS.md |
โ Archived | docs/archive/FINDINGS_AND_RECOMMENDATIONS.md |
docs/auth/comprehensive-implementation-plan.md |
โ Archived | docs/archive/comprehensive-implementation-plan.md |
For Developers:
For AI Assistants:
For Documentation Maintainers:
Status
column to track documentation lifecycleA comprehensive demo application is included in src/demo-app/
that showcases all features of the flows-auth library. The demo includes:
# Navigate to demo app
cd src/demo-app
# Install dependencies
pnpm install
# Start development server
pnpm dev
# Build for production
pnpm build
The demo app is also deployed automatically to GitHub Pages: View Live Demo
<!-- examples/basic/App.svelte -->
<script>
import { SignInForm } from '@thepia/flows-auth';
const config = {
apiBaseUrl: 'https://api.example.com',
clientId: 'demo-client',
domain: 'example.com',
enablePasskeys: true,
enableMagicLinks: true,
branding: {
companyName: 'Demo Company'
}
};
</script>
<SignInForm {config} />
<!-- examples/whitelabel/App.svelte -->
<script>
import { SignInForm } from '@thepia/flows-auth';
const config = {
apiBaseUrl: process.env.VITE_API_URL,
clientId: process.env.VITE_CLIENT_ID,
domain: process.env.VITE_DOMAIN,
enablePasskeys: true,
branding: {
companyName: process.env.VITE_COMPANY_NAME,
logoUrl: process.env.VITE_LOGO_URL,
primaryColor: process.env.VITE_PRIMARY_COLOR,
customCSS: `
.auth-form {
--auth-border-radius: 0;
--auth-shadow: none;
border: 2px solid var(--auth-primary-color);
}
`
}
};
</script>
<SignInForm {config} compact />
The library includes comprehensive test utilities:
import { render, fireEvent } from '@testing-library/svelte';
import { createMockAuthConfig } from '@thepia/flows-auth/testing';
import SignInForm from '@thepia/flows-auth';
test('sign in flow', async () => {
const config = createMockAuthConfig();
const { getByLabelText, getByText } = render(SignInForm, { config });
await fireEvent.input(getByLabelText('Email'), {
target: { value: '[email protected]' }
});
await fireEvent.click(getByText('Continue'));
// Assert passkey step appears
expect(getByText('Use your passkey')).toBeInTheDocument();
});
If you're migrating from the React version:
on:event
syntax instead of onEvent
propsSee the Migration Guide for detailed instructions.
# Install dependencies
pnpm install
# Run tests
pnpm test
# Build library
pnpm build
# Run examples
pnpm example:flows-app-demo
pnpm example:tasks-app-demo
When developing flows-auth alongside a consuming project (like flows.thepia.net), you can use pnpm link for live updates that automatically reflect changes without manual reinstallation:
# Step 1: In flows-auth directory - create global link
cd /path/to/flows-auth
pnpm link --global
# Step 2: In your consuming project - use the global link
cd /path/to/your-project
pnpm link --global @thepia/flows-auth
# Now changes in flows-auth will automatically be available in your project
# You still need to build flows-auth after making changes:
cd /path/to/flows-auth
pnpm build
# Changes are now live in your consuming project!
Troubleshooting pnpm link issues:
If you encounter "Symlink path is the same as the target path" error:
# Clear existing global links
pnpm unlink --global @thepia/flows-auth
# Remove from consuming project
cd /path/to/your-project
pnpm unlink --global @thepia/flows-auth
# Clean install in consuming project
rm -rf node_modules/@thepia/flows-auth
pnpm install
# Try linking again
cd /path/to/flows-auth
pnpm link --global
cd /path/to/your-project
pnpm link --global @thepia/flows-auth
If linking continues to fail, use the manual install method below.
If you prefer not to use global links, you can manually update after each build:
# After building flows-auth
cd /path/to/your-project
rm -rf node_modules/@thepia/flows-auth
pnpm install
Note: The file:../flows-auth
dependency method requires manual reinstallation after each build, as pnpm copies files at install time rather than creating live links.
MIT License - see LICENSE file for details.