@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.
- package/esm2022/lib/recaptcha.service.mjs +359 -0
- package/esm2022/lib/social-redirect-callback.guard.mjs +28 -21
- package/esm2022/ngmodule/auth.service.mjs +94 -12
- package/esm2022/ngmodule/tokens.mjs +1 -1
- package/esm2022/public-api.mjs +2 -1
- package/fesm2022/nauth-toolkit-client-angular.mjs +477 -33
- package/fesm2022/nauth-toolkit-client-angular.mjs.map +1 -1
- package/lib/recaptcha.service.d.ts +195 -0
- package/lib/social-redirect-callback.guard.d.ts +1 -0
- package/ngmodule/auth.service.d.ts +45 -10
- package/ngmodule/tokens.d.ts +97 -0
- package/package.json +2 -2
- package/public-api.d.ts +1 -0
|
@@ -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
|
-
*
|
|
116
|
-
*
|
|
117
|
-
*
|
|
118
|
-
*
|
|
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
|
-
|
|
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
|
}
|
package/ngmodule/tokens.d.ts
CHANGED
|
@@ -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.
|
|
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.
|
|
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