Official Angular client library for StoneScriptPHP backend framework
Note: While published as @progalaxyelabs/ngx-stonescriptphp-client, this is the official client for StoneScriptPHP. Future versions will migrate to the @stonescriptphp namespace.
Current Version: 1.8.1
- v1.8.1: Renamed
authServertoaccountsServerfor naming consistency - v1.8.0: Added
accountsServerproperty for microservices architecture - v1.7.1: Fixed URL concatenation (removed trailing slash requirement)
Fully compatible with StoneScriptPHP Framework v2.1.x authentication!
- ✅ Cookie-based auth: Secure httpOnly cookies + CSRF (StoneScriptPHP v2.1.x default)
- ✅ Body-based auth: Legacy mode for custom backends
- ✅ Configurable: Choose your auth strategy via environment config
- ✅ All HTTP methods: GET, POST, PUT, PATCH, DELETE with automatic token refresh
- ✅ Multiple identity providers: Authenticate against different auth servers (customer auth vs employee auth)
- ✅ Runtime server switching: Switch between auth servers dynamically
- ✅ Per-request server selection: Specify server for individual auth calls
- ✅ Backward compatible: Single-server config still works
- ✅ Use case: Shared admin platforms that accept both customer and employee logins
// Multi-server configuration
authServers: {
customer: { url: 'https://auth.progalaxyelabs.com', default: true },
employee: { url: 'https://admin-auth.progalaxyelabs.com' }
}See MULTI-AUTH-SERVER.md for complete documentation.
- ✅ AuthPageComponent: Embeddable full-page auth with custom branding
- ✅ Customizable Branding: Logo, colors, gradients, app name, subtitle
- ✅ Login/Register Toggle: Seamless switching between modes
- ✅ Styled Card Layout: Professional gradient background with centered card
- ✅ Zero Configuration: Works out-of-the-box with sensible defaults
// Quick Example: Branded auth page
<lib-auth-page
[providers]="['google', 'emailPassword']"
(authenticated)="onAuth($event)">
</lib-auth-page>- ✅ 6 Auth Providers: Google, LinkedIn, Apple, Microsoft, GitHub, Email/Password
- ✅ Declarative Configuration: Enable/disable providers via environment
- ✅ Popup OAuth: Social login via popup windows (no full-page redirects)
- ✅ Fetch API: Promise-based authentication (minimal RxJS)
- ✅ Observable User State: Reactive
user$for UI updates
// Quick Example: Configure auth providers
authProviders: {
google: { label: 'Sign in with Google', enabled: true },
linkedin: { label: 'Sign in with LinkedIn', enabled: true },
emailPassword: { label: 'Email', enabled: true }
}See Configuration and AUTH-PROVIDER-CONFIG.md for details.
After login or registration, the library stores the authenticated user. Access it in any component:
import { AuthService, User } from '@progalaxyelabs/ngx-stonescriptphp-client';
@Component({ ... })
export class MyComponent {
constructor(private authService: AuthService) {}
ngOnInit() {
// Snapshot — current user or null if not authenticated
const user: User | null = this.authService.getCurrentUser();
if (user) {
console.log(user.display_name); // "John Doe"
console.log(user.email); // "john@example.com"
console.log(user.photo_url); // avatar URL (optional)
console.log(user.is_email_verified);
}
// Reactive — emits on login, logout, and token refresh
this.authService.user$.subscribe(user => {
// user is User | null
});
}
}The User object is persisted in localStorage and restored on page refresh. It is populated from the auth service API response (not from the JWT token).
For architectures where roles are owned by the platform (not the auth service), use the token exchange flow:
import { AuthService } from '@progalaxyelabs/ngx-stonescriptphp-client';
@Component({ ... })
export class AppComponent {
constructor(private authService: AuthService) {}
async ngOnInit() {
// After login, check if token exchange is needed
if (this.authService.needsTokenExchange()) {
const result = await this.authService.exchangeToken();
if (result.success) {
console.log('Token exchanged, role:', result.role);
}
}
}
}How it works:
- Auth service issues identity-only token (no roles)
- Call
exchangeToken()to exchange with platform API (/api/auth/exchange) - Platform returns token with roles from tenant DB
- Platform token is used for subsequent API calls
Methods:
exchangeToken(endpoint?)- Exchange identity token for platform tokenreExchangeToken(endpoint?)- Re-exchange using stored identity tokenneedsTokenExchange()- Check if current token lacks roles
📖 Documentation: CHANGELOG | Auth Compatibility | Provider Config | Modal Auth Spec | Multi-Auth Server
The Angular HTTP client library for StoneScriptPHP - a modern PHP backend framework that auto-generates TypeScript clients from your backend DTOs and contracts.
When you build APIs with StoneScriptPHP, you define:
- Request DTOs (TypeScript interfaces)
- Response DTOs (TypeScript interfaces)
- Route contracts (interfaces)
This library provides the HTTP client that consumes those contracts, giving you 100% type-safe API calls with zero manual typing.
- ✅ Type-safe HTTP calls - Full TypeScript support from backend DTOs
- ✅ Auto-generated clients - StoneScriptPHP generates TypeScript from PHP
- ✅ RxJS observables - Native Angular integration
- ✅ Error handling - Consistent error responses
- ✅ Interceptors ready - Add auth, logging, retry logic
- ✅ Angular 19+ & 20+ - Modern Angular standalone components
npm install @progalaxyelabs/ngx-stonescriptphp-clientIn your StoneScriptPHP project:
php stone generate typescript-clientThis generates TypeScript interfaces from your PHP DTOs.
import { Component } from '@angular/core';
import { HttpClient } from '@angular/common/http';
import { Observable } from 'rxjs';
// Auto-generated from StoneScriptPHP backend
interface ProductRequest {
name: string;
price: number;
}
interface ProductResponse {
productId: number;
status: string;
}
@Component({
selector: 'app-products',
standalone: true,
template: `<button (click)="createProduct()">Create Product</button>`
})
export class ProductsComponent {
constructor(private http: HttpClient) {}
createProduct(): void {
const request: ProductRequest = {
name: 'Widget',
price: 99.99
};
this.http.post<ProductResponse>('http://localhost:9100/products', request)
.subscribe(response => {
console.log('Product created:', response.productId);
});
}
}StoneScriptPHP follows a contract-first approach:
PHP Backend (StoneScriptPHP) Angular Frontend
┌─────────────────────────┐ ┌──────────────────────┐
│ ProductRequest DTO │ ──────> │ ProductRequest.ts │
│ ProductResponse DTO │ ──────> │ ProductResponse.ts │
│ IProductRoute contract │ ──────> │ Type-safe HTTP calls │
└─────────────────────────┘ └──────────────────────┘
- Define DTOs in PHP
- Run
php stone generate typescript-client - Import generated TypeScript interfaces in Angular
- Make type-safe HTTP calls
Important: As of v1.7.1, host URLs should NOT include trailing slashes. Endpoints should include leading slashes.
// app.config.ts
NgxStoneScriptPhpClientModule.forRoot({
// ✅ Correct: No trailing slash
apiServer: { host: 'http://localhost:3011' },
// ❌ Wrong: Has trailing slash
// apiServer: { host: 'http://localhost:3011/' },
})For Microservices:
If your authentication is on a different server than your API, use accountsServer (v1.8.1+):
NgxStoneScriptPhpClientModule.forRoot({
apiServer: { host: 'http://localhost:3011' }, // Business API
accountsServer: { host: 'http://localhost:3139' }, // Auth service
auth: {
mode: 'body',
refreshEndpoint: '/api/auth/refresh' // Just the path, no server URL
}
})Fallback chain for auth server:
accountsServer.host(if specified)accountsUrl(deprecated, for backward compatibility)apiServer.host(same-server auth)
Customize your authentication pages with your brand identity:
// app.config.ts or environment.ts
import { NgxStoneScriptPhpClientModule, MyEnvironmentModel } from '@progalaxyelabs/ngx-stonescriptphp-client';
export const appConfig: ApplicationConfig = {
providers: [
NgxStoneScriptPhpClientModule.forRoot({
apiServer: {
host: 'http://localhost:9100' // No trailing slash
},
branding: {
appName: 'My Platform', // Required: App name on auth pages
logo: '/assets/logo.png', // Optional: Logo URL
primaryColor: '#667eea', // Optional: Auto-generates gradient
gradientStart: '#667eea', // Optional: Custom gradient start
gradientEnd: '#764ba2', // Optional: Custom gradient end
subtitle: 'Secure authentication' // Optional: Subtitle text
}
} as MyEnvironmentModel)
]
};Using the AuthPageComponent:
import { Component } from '@angular/core';
import { AuthPageComponent, TenantSelectedEvent } from '@progalaxyelabs/ngx-stonescriptphp-client';
@Component({
selector: 'app-login',
standalone: true,
imports: [AuthPageComponent],
template: `
<lib-auth-page
[providers]="['google', 'linkedin', 'emailPassword']"
(authenticated)="onAuthenticated($event)">
</lib-auth-page>
`
})
export class LoginComponent {
onAuthenticated(event: TenantSelectedEvent) {
console.log('User authenticated:', event);
// Navigate to dashboard, etc.
}
}Branding Options:
| Option | Type | Description |
|---|---|---|
appName |
string |
Required. Application name displayed on auth pages |
logo |
string |
Optional. URL to logo image (max 200x80px recommended) |
primaryColor |
string |
Optional. Primary brand color (hex). Auto-generates gradient if no gradient colors provided |
gradientStart |
string |
Optional. Gradient start color (hex). Overrides primaryColor |
gradientEnd |
string |
Optional. Gradient end color (hex). Required if gradientStart is set |
subtitle |
string |
Optional. Subtitle text below app name |
Default Styling:
- Gradient:
linear-gradient(135deg, #667eea 0%, #764ba2 100%) - White card with rounded corners and shadow
- Responsive design (mobile-friendly)
Choose your authentication strategy based on your backend:
// environment.ts
export const environment = {
production: false,
apiServer: {
host: 'http://localhost:8000/'
},
auth: {
mode: 'cookie', // Default mode
refreshEndpoint: '/auth/refresh', // Default endpoint
useCsrf: true, // Default for cookie mode
refreshTokenCookieName: 'refresh_token', // Default
csrfTokenCookieName: 'csrf_token', // Default
csrfHeaderName: 'X-CSRF-Token' // Default
}
}Features:
- Secure httpOnly cookies prevent XSS attacks
- CSRF token protection
- Token rotation on refresh
- Works with StoneScriptPHP
AuthRoutes::register($router)
// environment.ts
export const environment = {
production: false,
apiServer: {
host: 'http://localhost:8000/'
},
auth: {
mode: 'body',
refreshEndpoint: '/user/refresh_access',
useCsrf: false
}
}Use when:
- Your backend accepts tokens in request body
- Custom authentication implementation
- Migrating from older systems
// environment.ts
export const environment = {
production: false,
apiServer: {
host: 'http://localhost:8000/'
},
auth: {
mode: 'none'
}
}Use when:
- You handle token refresh manually
- No authentication needed
- Custom auth logic
import { HttpInterceptor, HttpRequest, HttpHandler } from '@angular/common/http';
export class AuthInterceptor implements HttpInterceptor {
intercept(req: HttpRequest<any>, next: HttpHandler) {
const authReq = req.clone({
headers: req.headers.set('Authorization', 'Bearer ' + getToken())
});
return next.handle(authReq);
}
}this.http.post<ProductResponse>('/products', request)
.pipe(
catchError(error => {
console.error('API Error:', error);
return throwError(() => error);
})
)
.subscribe(response => {
// Handle success
});StoneScriptPHP responses follow this structure:
{
"status": "ok" | "error",
"message": "Success message",
"data": { /* Your DTO */ }
}- Angular >= 19.0.0 or 20.0.0
- RxJS >= 7.8.0
- TypeScript >= 5.8.0
- Framework Docs: stonescriptphp.org
- Getting Started: stonescriptphp.org/docs/getting-started
- TypeScript Client Guide: stonescriptphp.org/docs/typescript-client
Check out the StoneScriptPHP examples repository for full-stack example apps.
This is part of the StoneScriptPHP ecosystem. Contributions welcome!
- Report issues: GitHub Issues
- Framework repo: StoneScriptPHP
MIT
- StoneScriptPHP - The PHP backend framework
- sunbird-garden - Reference implementation
Made with ❤️ by the StoneScriptPHP team