@nauth-toolkit/client-angular 0.1.91 → 0.1.92

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,195 @@
1
+ import { InjectionToken } from '@angular/core';
2
+ import * as i0 from "@angular/core";
3
+ /**
4
+ * Detects the current platform environment
5
+ */
6
+ type Platform = 'web' | 'capacitor-webview' | 'capacitor-native' | 'ssr';
7
+ /**
8
+ * reCAPTCHA version type
9
+ */
10
+ type RecaptchaVersion = 'v2' | 'v3' | 'enterprise';
11
+ /**
12
+ * reCAPTCHA configuration for RecaptchaService
13
+ *
14
+ * Internal configuration interface used by RecaptchaService.
15
+ * Use RecaptchaAngularConfig from tokens.ts for app configuration.
16
+ */
17
+ export interface RecaptchaServiceConfig {
18
+ enabled: boolean;
19
+ version: RecaptchaVersion;
20
+ siteKey: string;
21
+ action?: string;
22
+ autoLoadScript?: boolean;
23
+ language?: string;
24
+ }
25
+ /**
26
+ * Injection token for reCAPTCHA configuration
27
+ */
28
+ export declare const RECAPTCHA_CONFIG: InjectionToken<RecaptchaServiceConfig>;
29
+ /**
30
+ * Google reCAPTCHA service for Angular applications.
31
+ *
32
+ * Provides lazy loading of reCAPTCHA script and platform-aware token generation.
33
+ * Automatically detects platform (web, Capacitor WebView, Capacitor native, SSR)
34
+ * and skips reCAPTCHA in environments where it's not supported or needed.
35
+ *
36
+ * Features:
37
+ * - Lazy script loading (only loads when needed)
38
+ * - v2 (checkbox) and v3 (invisible) support
39
+ * - Platform detection (web, Capacitor, SSR)
40
+ * - Automatic skip for Capacitor native mode
41
+ * - Automatic skip for SSR
42
+ *
43
+ * @example v3 Automatic Mode
44
+ * ```typescript
45
+ * constructor(private recaptcha: RecaptchaService) {}
46
+ *
47
+ * async login() {
48
+ * const token = await this.recaptcha.execute('login');
49
+ * await this.auth.login(email, password, token);
50
+ * }
51
+ * ```
52
+ *
53
+ * @example v2 Manual Mode
54
+ * ```typescript
55
+ * ngOnInit() {
56
+ * this.recaptcha.render('recaptcha-container', (token) => {
57
+ * this.recaptchaToken = token;
58
+ * });
59
+ * }
60
+ * ```
61
+ */
62
+ export declare class RecaptchaService {
63
+ private platformId;
64
+ private config?;
65
+ private scriptLoaded;
66
+ private scriptLoading;
67
+ private platform;
68
+ private widgetId;
69
+ constructor(platformId: string, config?: RecaptchaServiceConfig);
70
+ /**
71
+ * Detect the current platform environment.
72
+ *
73
+ * Detection priority:
74
+ * 1. SSR (not in browser) → 'ssr'
75
+ * 2. Capacitor native (no web view) → 'capacitor-native'
76
+ * 3. Capacitor WebView → 'capacitor-webview'
77
+ * 4. Web browser → 'web'
78
+ *
79
+ * @returns Detected platform type
80
+ *
81
+ * @example
82
+ * ```typescript
83
+ * const platform = this.detectPlatform();
84
+ * if (platform === 'capacitor-native') {
85
+ * // Skip reCAPTCHA, use device attestation
86
+ * }
87
+ * ```
88
+ */
89
+ private detectPlatform;
90
+ /**
91
+ * Get the current platform.
92
+ *
93
+ * @returns Current platform type
94
+ */
95
+ getPlatform(): Platform;
96
+ /**
97
+ * Check if reCAPTCHA should be skipped for current platform.
98
+ *
99
+ * Skips for:
100
+ * - SSR (no window object)
101
+ * - Capacitor native (use device attestation instead)
102
+ *
103
+ * @returns True if should skip reCAPTCHA
104
+ */
105
+ shouldSkip(): boolean;
106
+ /**
107
+ * Load Google reCAPTCHA script if not already loaded.
108
+ *
109
+ * Script URL format:
110
+ * - v2: https://www.google.com/recaptcha/api.js
111
+ * - v3: https://www.google.com/recaptcha/api.js?render={siteKey}
112
+ * - Enterprise: https://www.google.com/recaptcha/enterprise.js?render={siteKey}
113
+ *
114
+ * @returns Promise that resolves when script is loaded
115
+ *
116
+ * @throws Error if config is missing or script fails to load
117
+ */
118
+ loadScript(): Promise<void>;
119
+ /**
120
+ * Inject the reCAPTCHA script into the DOM.
121
+ *
122
+ * @returns Promise that resolves when script loads
123
+ */
124
+ private injectScript;
125
+ /**
126
+ * Execute reCAPTCHA v3/Enterprise challenge (invisible).
127
+ *
128
+ * Automatically loads script if needed and generates a token.
129
+ * Skips automatically for SSR and Capacitor native.
130
+ *
131
+ * @param action - Action name for v3 analytics (e.g., 'login', 'signup')
132
+ * @returns Promise resolving to reCAPTCHA token, or undefined if skipped
133
+ *
134
+ * @throws Error if version is v2, config missing, or execution fails
135
+ *
136
+ * @example
137
+ * ```typescript
138
+ * const token = await this.recaptcha.execute('login');
139
+ * if (token) {
140
+ * await this.auth.login(email, password, token);
141
+ * }
142
+ * ```
143
+ */
144
+ execute(action?: string): Promise<string | undefined>;
145
+ /**
146
+ * Render reCAPTCHA v2 checkbox widget.
147
+ *
148
+ * @param containerId - DOM element ID or element to render in
149
+ * @param callback - Callback when user completes challenge
150
+ * @returns Promise resolving to widget ID
151
+ *
152
+ * @throws Error if version is not v2, config missing, or render fails
153
+ *
154
+ * @example
155
+ * ```typescript
156
+ * ngAfterViewInit() {
157
+ * this.recaptcha.render('recaptcha-container', (token) => {
158
+ * this.recaptchaToken = token;
159
+ * this.loginForm.patchValue({ recaptchaToken: token });
160
+ * });
161
+ * }
162
+ * ```
163
+ */
164
+ render(containerId: string, callback: (token: string) => void): Promise<number>;
165
+ /**
166
+ * Get response token from v2 widget.
167
+ *
168
+ * @param widgetId - Widget ID (optional, uses last rendered widget if not provided)
169
+ * @returns reCAPTCHA token or null if not completed
170
+ *
171
+ * @example
172
+ * ```typescript
173
+ * const token = this.recaptcha.getResponse();
174
+ * if (token) {
175
+ * await this.auth.login(email, password, token);
176
+ * }
177
+ * ```
178
+ */
179
+ getResponse(widgetId?: number): string | null;
180
+ /**
181
+ * Reset v2 widget (clear response).
182
+ *
183
+ * @param widgetId - Widget ID (optional, uses last rendered widget if not provided)
184
+ *
185
+ * @example
186
+ * ```typescript
187
+ * // After failed login
188
+ * this.recaptcha.reset();
189
+ * ```
190
+ */
191
+ reset(widgetId?: number): void;
192
+ static ɵfac: i0.ɵɵFactoryDeclaration<RecaptchaService, [null, { optional: true; }]>;
193
+ static ɵprov: i0.ɵɵInjectableDeclaration<RecaptchaService>;
194
+ }
195
+ export {};
@@ -12,6 +12,7 @@ import { type CanActivateFn } from '@angular/router';
12
12
  * - If `exchangeToken` exists: exchanges it via backend (SDK handles navigation automatically).
13
13
  * - If no `exchangeToken`: treat as cookie-success path (SDK handles navigation automatically).
14
14
  * - If `error` exists: redirects to oauthError route.
15
+ * - If auto-redirect is disabled (redirectUrls set to null): returns true to activate the route.
15
16
  *
16
17
  * @example
17
18
  * ```typescript
@@ -1,6 +1,7 @@
1
1
  import { Router } from '@angular/router';
2
2
  import { Observable } from 'rxjs';
3
3
  import { AngularHttpAdapter } from './http-adapter';
4
+ import { RecaptchaService } from '../lib/recaptcha.service';
4
5
  import { NAuthClient, NAuthClientConfig, ChallengeResponse, AuthResponse, TokenResponse, AuthUser, ConfirmForgotPasswordResponse, ForgotPasswordResponse, ResetPasswordWithCodeResponse, UpdateProfileRequest, GetChallengeDataResponse, GetSetupDataResponse, MFAStatus, MFADevice, AuthEvent, SocialProvider, SocialLoginOptions, LinkedAccountsResponse, SocialVerifyRequest, AuditHistoryResponse, AdminOperations } from '@nauth-toolkit/client';
5
6
  import * as i0 from "@angular/core";
6
7
  /**
@@ -37,6 +38,7 @@ import * as i0 from "@angular/core";
37
38
  */
38
39
  export declare class AuthService {
39
40
  private router?;
41
+ private recaptchaService?;
40
42
  private readonly client;
41
43
  private readonly config;
42
44
  private readonly currentUserSubject;
@@ -48,8 +50,9 @@ export declare class AuthService {
48
50
  * @param config - Injected client configuration (required)
49
51
  * @param httpAdapter - Angular HTTP adapter for making requests (required)
50
52
  * @param router - Angular Router (optional, automatically used for navigation if available)
53
+ * @param recaptchaService - RecaptchaService (optional, for automatic token generation)
51
54
  */
52
- constructor(config: NAuthClientConfig, httpAdapter: AngularHttpAdapter, router?: Router);
55
+ constructor(config: NAuthClientConfig, httpAdapter: AngularHttpAdapter, router?: Router, recaptchaService?: RecaptchaService);
53
56
  /**
54
57
  * Current user observable.
55
58
  */
@@ -105,28 +108,35 @@ export declare class AuthService {
105
108
  /**
106
109
  * Login with identifier and password.
107
110
  *
111
+ * Automatically generates reCAPTCHA token if configured (v3 only).
112
+ * For v2 manual mode, pass the token explicitly.
113
+ *
108
114
  * @param identifier - User email or username
109
115
  * @param password - User password
116
+ * @param recaptchaToken - Optional reCAPTCHA token (for v2 manual mode or when auto-generation is disabled)
110
117
  * @returns Promise with auth response or challenge
111
118
  *
112
- * @example
119
+ * @example Basic Login
113
120
  * ```typescript
114
121
  * const response = await this.auth.login('user@example.com', 'password');
115
- * if (response.challengeName) {
116
- * // Handle challenge
117
- * } else {
118
- * // Login successful
119
- * }
122
+ * ```
123
+ *
124
+ * @example With Manual reCAPTCHA (v2)
125
+ * ```typescript
126
+ * const response = await this.auth.login('user@example.com', 'password', recaptchaToken);
120
127
  * ```
121
128
  */
122
- login(identifier: string, password: string): Promise<AuthResponse>;
129
+ login(identifier: string, password: string, recaptchaToken?: string): Promise<AuthResponse>;
123
130
  /**
124
131
  * Signup with credentials.
125
132
  *
133
+ * Automatically generates reCAPTCHA token if configured (v3 only).
134
+ * For v2 manual mode, include token in payload.
135
+ *
126
136
  * @param payload - Signup request payload
127
137
  * @returns Promise with auth response or challenge
128
138
  *
129
- * @example
139
+ * @example Basic Signup
130
140
  * ```typescript
131
141
  * const response = await this.auth.signup({
132
142
  * email: 'new@example.com',
@@ -134,6 +144,15 @@ export declare class AuthService {
134
144
  * firstName: 'John',
135
145
  * });
136
146
  * ```
147
+ *
148
+ * @example With Manual reCAPTCHA (v2)
149
+ * ```typescript
150
+ * const response = await this.auth.signup({
151
+ * email: 'new@example.com',
152
+ * password: 'SecurePass123!',
153
+ * recaptchaToken: token,
154
+ * });
155
+ * ```
137
156
  */
138
157
  signup(payload: Parameters<NAuthClient['signup']>[0]): Promise<AuthResponse>;
139
158
  /**
@@ -655,6 +674,22 @@ export declare class AuthService {
655
674
  * Update challenge state after auth response.
656
675
  */
657
676
  private updateChallengeState;
658
- static ɵfac: i0.ɵɵFactoryDeclaration<AuthService, [null, null, { optional: true; }]>;
677
+ /**
678
+ * Get reCAPTCHA token - auto-generate for v3 or use provided token.
679
+ *
680
+ * Handles platform detection:
681
+ * - Web browser: Generate token if enabled and v3
682
+ * - Capacitor native: Skip (use device attestation instead)
683
+ * - SSR: Skip
684
+ * - Manual mode (v2 or manualChallenge=true): Requires explicit token
685
+ *
686
+ * @param providedToken - Explicitly provided token (v2 manual mode)
687
+ * @param action - Action name for v3 analytics
688
+ * @returns reCAPTCHA token or undefined
689
+ *
690
+ * @private
691
+ */
692
+ private getRecaptchaToken;
693
+ static ɵfac: i0.ɵɵFactoryDeclaration<AuthService, [null, null, { optional: true; }, { optional: true; }]>;
659
694
  static ɵprov: i0.ɵɵInjectableDeclaration<AuthService>;
660
695
  }
@@ -1,5 +1,102 @@
1
1
  import { InjectionToken } from '@angular/core';
2
2
  import { NAuthClientConfig } from '@nauth-toolkit/client';
3
+ /**
4
+ * reCAPTCHA configuration for Angular client.
5
+ *
6
+ * Extends base client RecaptchaConfig with Angular-specific options.
7
+ *
8
+ * @example v3 Automatic Mode
9
+ * ```typescript
10
+ * {
11
+ * enabled: true,
12
+ * version: 'v3',
13
+ * siteKey: '6LcExample_Site_Key',
14
+ * action: 'login',
15
+ * autoLoadScript: true,
16
+ * }
17
+ * ```
18
+ *
19
+ * @example v2 Manual Mode
20
+ * ```typescript
21
+ * {
22
+ * enabled: true,
23
+ * version: 'v2',
24
+ * siteKey: '6LcExample_Site_Key',
25
+ * manualChallenge: true,
26
+ * }
27
+ * ```
28
+ */
29
+ export interface RecaptchaAngularConfig {
30
+ /**
31
+ * Enable/disable reCAPTCHA.
32
+ * Set to false to disable even if configured (useful for testing).
33
+ */
34
+ enabled: boolean;
35
+ /**
36
+ * reCAPTCHA version: v2 (checkbox), v3 (invisible), or enterprise.
37
+ */
38
+ version: 'v2' | 'v3' | 'enterprise';
39
+ /**
40
+ * Site key from Google reCAPTCHA console.
41
+ * This is safe to expose publicly (it's the public key).
42
+ */
43
+ siteKey: string;
44
+ /**
45
+ * Action name for v3/Enterprise analytics.
46
+ * Helps track which actions are being protected.
47
+ * Common values: 'login', 'signup', 'submit'
48
+ *
49
+ * @default 'submit'
50
+ */
51
+ action?: string;
52
+ /**
53
+ * Manual challenge mode (v2 only).
54
+ * If true, you must manually call RecaptchaService.render() and get token.
55
+ * If false, AuthService auto-generates token before login/signup.
56
+ *
57
+ * @default false
58
+ */
59
+ manualChallenge?: boolean;
60
+ /**
61
+ * Automatically load the Google reCAPTCHA script.
62
+ * If false, you must manually load the script.
63
+ *
64
+ * @default true
65
+ */
66
+ autoLoadScript?: boolean;
67
+ /**
68
+ * Language code for reCAPTCHA widget (v2 only).
69
+ * @example 'en', 'es', 'fr', 'de'
70
+ * @default Browser language
71
+ */
72
+ language?: string;
73
+ }
74
+ /**
75
+ * Angular-specific NAuth configuration.
76
+ *
77
+ * Extends base NAuthClientConfig with Angular-specific options.
78
+ *
79
+ * @example
80
+ * ```typescript
81
+ * const config: NAuthAngularConfig = {
82
+ * baseUrl: 'https://api.example.com/auth',
83
+ * tokenDelivery: 'cookies',
84
+ * recaptcha: {
85
+ * enabled: true,
86
+ * version: 'v3',
87
+ * siteKey: '6LcExample_Site_Key',
88
+ * action: 'login',
89
+ * },
90
+ * };
91
+ * ```
92
+ */
93
+ export interface NAuthAngularConfig extends NAuthClientConfig {
94
+ /**
95
+ * Google reCAPTCHA configuration (optional).
96
+ * Provides bot protection for login/signup endpoints.
97
+ */
98
+ recaptcha?: RecaptchaAngularConfig;
99
+ }
3
100
  /**
4
101
  * Injection token for providing NAuthClientConfig in Angular apps.
5
102
  */
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@nauth-toolkit/client-angular",
3
- "version": "0.1.91",
3
+ "version": "0.1.92",
4
4
  "description": "Angular adapter for nauth-toolkit client SDK",
5
5
  "keywords": [
6
6
  "nauth",
@@ -24,7 +24,7 @@
24
24
  "peerDependencies": {
25
25
  "@angular/common": ">=17.0.0",
26
26
  "@angular/core": ">=17.0.0",
27
- "@nauth-toolkit/client": "^0.1.91",
27
+ "@nauth-toolkit/client": "^0.1.92",
28
28
  "rxjs": "^7.0.0 || ^8.0.0"
29
29
  },
30
30
  "dependencies": {
package/public-api.d.ts CHANGED
@@ -13,3 +13,4 @@ export * from './ngmodule/nauth.module';
13
13
  export * from './lib/auth.interceptor';
14
14
  export * from './lib/auth.guard';
15
15
  export * from './lib/social-redirect-callback.guard';
16
+ export * from './lib/recaptcha.service';