siarashield_workspace 0.0.48 → 0.0.52
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/README.md +100 -86
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -10,22 +10,83 @@ Angular integration for CyberSiara **SiaraShield** captcha.
|
|
|
10
10
|
- `@angular/core >=16.0.0 <22.0.0`
|
|
11
11
|
- `@angular/common >=16.0.0 <22.0.0`
|
|
12
12
|
|
|
13
|
-
##
|
|
13
|
+
## Install
|
|
14
14
|
|
|
15
|
-
|
|
15
|
+
```bash
|
|
16
|
+
npm i siarashield_workspace
|
|
17
|
+
```
|
|
16
18
|
|
|
17
|
-
|
|
19
|
+
## Quick setup (recommended)
|
|
20
|
+
|
|
21
|
+
This is the easiest and most reliable flow. It applies all CSP wiring automatically.
|
|
18
22
|
|
|
19
23
|
```bash
|
|
20
|
-
|
|
24
|
+
ng add siarashield_workspace
|
|
21
25
|
```
|
|
22
26
|
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
+
If your `angular.json` does not have a `defaultProject`, pass the project name:
|
|
28
|
+
|
|
29
|
+
```bash
|
|
30
|
+
ng add siarashield_workspace --project <yourProjectName>
|
|
31
|
+
```
|
|
32
|
+
|
|
33
|
+
What `ng add` does:
|
|
34
|
+
- Updates `src/index.html` (adds `meta[name="csp-nonce"]` + CSP policy)
|
|
35
|
+
- Updates `src/app/app.config.ts` (standalone) **or** `src/main.ts` (fallback) to provide Angular `CSP_NONCE`
|
|
36
|
+
|
|
37
|
+
## Manual setup (if you don’t want `ng add`)
|
|
38
|
+
|
|
39
|
+
### Step 1: Add CSP meta tags in `src/index.html`
|
|
40
|
+
|
|
41
|
+
Copy/paste:
|
|
42
|
+
|
|
43
|
+
```html
|
|
44
|
+
<meta name="csp-nonce" content="REPLACE_WITH_NONCE" />
|
|
45
|
+
<meta http-equiv="Content-Security-Policy" content="
|
|
46
|
+
default-src 'self';
|
|
47
|
+
script-src 'self' 'nonce-REPLACE_WITH_NONCE' https://embed.mycybersiara.com https://embedcdn.mycybersiara.com;
|
|
48
|
+
script-src-elem 'self' 'nonce-REPLACE_WITH_NONCE' https://embed.mycybersiara.com https://embedcdn.mycybersiara.com;
|
|
49
|
+
script-src-attr 'self' 'unsafe-inline';
|
|
50
|
+
connect-src 'self' https://embed.mycybersiara.com https://embedcdn.mycybersiara.com;
|
|
51
|
+
style-src 'self' 'nonce-REPLACE_WITH_NONCE' https://embed.mycybersiara.com https://mycybersiara.com https://fonts.googleapis.com https://cdnjs.cloudflare.com;
|
|
52
|
+
style-src-elem 'self' 'nonce-REPLACE_WITH_NONCE' https://embed.mycybersiara.com https://mycybersiara.com https://fonts.googleapis.com https://cdnjs.cloudflare.com;
|
|
53
|
+
style-src-attr 'self' 'unsafe-inline';
|
|
54
|
+
font-src 'self' https://fonts.gstatic.com https://mycybersiara.com https://cdnjs.cloudflare.com data:;
|
|
55
|
+
img-src 'self' data: https://embed.mycybersiara.com https://embedcdn.mycybersiara.com https://mycybersiara.com;
|
|
56
|
+
">
|
|
57
|
+
```
|
|
27
58
|
|
|
28
|
-
|
|
59
|
+
### Step 2: Provide Angular `CSP_NONCE` (recommended)
|
|
60
|
+
|
|
61
|
+
In `src/app/app.config.ts`:
|
|
62
|
+
|
|
63
|
+
```ts
|
|
64
|
+
import { ApplicationConfig, CSP_NONCE } from '@angular/core';
|
|
65
|
+
|
|
66
|
+
export const appConfig: ApplicationConfig = {
|
|
67
|
+
providers: [
|
|
68
|
+
{
|
|
69
|
+
provide: CSP_NONCE,
|
|
70
|
+
useFactory: () =>
|
|
71
|
+
document.querySelector('meta[name="csp-nonce"]')?.getAttribute('content') ?? null,
|
|
72
|
+
},
|
|
73
|
+
// ...your other providers...
|
|
74
|
+
],
|
|
75
|
+
};
|
|
76
|
+
```
|
|
77
|
+
|
|
78
|
+
### Step 3: Remove old `cspNonce` plumbing (recommended)
|
|
79
|
+
|
|
80
|
+
You normally **do not need** to pass `cspNonce` from your component.
|
|
81
|
+
|
|
82
|
+
Remove these if present:
|
|
83
|
+
- `[cspNonce]="cspNonce"` in the template
|
|
84
|
+
- `protected readonly cspNonce = ...` in the component
|
|
85
|
+
- `(window as any).__cspNonce` usage
|
|
86
|
+
|
|
87
|
+
## Quick start (component integration)
|
|
88
|
+
|
|
89
|
+
### 1) Put public key in environment
|
|
29
90
|
|
|
30
91
|
```ts
|
|
31
92
|
export const environment = {
|
|
@@ -33,19 +94,18 @@ export const environment = {
|
|
|
33
94
|
};
|
|
34
95
|
```
|
|
35
96
|
|
|
36
|
-
|
|
97
|
+
### 2) Render component + submit button in template
|
|
37
98
|
|
|
38
99
|
```html
|
|
39
100
|
<siara-shield
|
|
40
101
|
[publicKey]="environment.siaraShieldPublicKey"
|
|
41
|
-
[cspNonce]="cspNonce"
|
|
42
102
|
(token)="onCaptchaToken($event)"
|
|
43
103
|
></siara-shield>
|
|
44
104
|
|
|
45
105
|
<button type="submit" class="CaptchaSubmit" (click)="onSubmit()">Submit</button>
|
|
46
106
|
```
|
|
47
107
|
|
|
48
|
-
|
|
108
|
+
### 3) Check captcha before API submit
|
|
49
109
|
|
|
50
110
|
```ts
|
|
51
111
|
import { Component, ViewChild } from '@angular/core';
|
|
@@ -60,7 +120,6 @@ import { SiaraShieldComponent } from 'siarashield_workspace';
|
|
|
60
120
|
})
|
|
61
121
|
export class FormComponent {
|
|
62
122
|
protected readonly environment = environment;
|
|
63
|
-
protected readonly cspNonce = (window as any).__cspNonce as string | undefined;
|
|
64
123
|
|
|
65
124
|
private isSubmitting = false;
|
|
66
125
|
@ViewChild(SiaraShieldComponent) private readonly captcha?: SiaraShieldComponent;
|
|
@@ -85,36 +144,16 @@ export class FormComponent {
|
|
|
85
144
|
}
|
|
86
145
|
```
|
|
87
146
|
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
## Key handling (required)
|
|
91
|
-
|
|
92
|
-
- **Frontend (Angular): public key only**
|
|
93
|
-
- **Backend (.env or secret store): private key only**
|
|
94
|
-
|
|
95
|
-
Backend example:
|
|
96
|
-
|
|
97
|
-
```dotenv
|
|
98
|
-
SIARASHIELD_PRIVATE_KEY=YOUR-PRIVATE-KEY
|
|
99
|
-
```
|
|
100
|
-
|
|
101
|
-
Never place the private key in Angular code or browser-accessible files.
|
|
102
|
-
|
|
103
|
-
Get keys from [mycybersiara.com](https://mycybersiara.com).
|
|
147
|
+
## Legacy/optional: passing `cspNonce` explicitly
|
|
104
148
|
|
|
105
|
-
|
|
149
|
+
If you already have a server-generated nonce available in code, you can still pass it:
|
|
150
|
+
- Component input: `[cspNonce]="myNonce"`
|
|
151
|
+
- Function API: `initSiaraShield({ ..., cspNonce: myNonce })`
|
|
106
152
|
|
|
107
|
-
-
|
|
108
|
-
- **Recommended:** `<siara-shield ...>`
|
|
109
|
-
- **Alternative:** function API
|
|
110
|
-
- Do not mix both styles on the same page.
|
|
111
|
-
- Keep submit button class: `CaptchaSubmit`.
|
|
112
|
-
- Initialize captcha once per page load.
|
|
153
|
+
If omitted, the plugin auto-resolves the nonce from `meta[name="csp-nonce"]` or an existing `script[nonce]`.
|
|
113
154
|
|
|
114
155
|
## Function API (alternative)
|
|
115
156
|
|
|
116
|
-
Use this only when component integration is not possible.
|
|
117
|
-
|
|
118
157
|
Template:
|
|
119
158
|
|
|
120
159
|
```html
|
|
@@ -136,7 +175,7 @@ export class FormComponent {
|
|
|
136
175
|
private async initializeCaptcha() {
|
|
137
176
|
await initSiaraShield({
|
|
138
177
|
publicKey: environment.siaraShieldPublicKey,
|
|
139
|
-
cspNonce:
|
|
178
|
+
// cspNonce: 'optional-explicit-nonce',
|
|
140
179
|
});
|
|
141
180
|
}
|
|
142
181
|
|
|
@@ -150,48 +189,45 @@ export class FormComponent {
|
|
|
150
189
|
}
|
|
151
190
|
```
|
|
152
191
|
|
|
192
|
+
## Key handling (required)
|
|
193
|
+
|
|
194
|
+
- **Frontend (Angular): public key only**
|
|
195
|
+
- **Backend (.env or secret store): private key only**
|
|
196
|
+
|
|
197
|
+
Backend example:
|
|
198
|
+
|
|
199
|
+
```dotenv
|
|
200
|
+
SIARASHIELD_PRIVATE_KEY=YOUR-PRIVATE-KEY
|
|
201
|
+
```
|
|
202
|
+
|
|
203
|
+
Never place the private key in Angular code or browser-accessible files.
|
|
204
|
+
|
|
205
|
+
Get keys from [mycybersiara.com](https://mycybersiara.com).
|
|
206
|
+
|
|
153
207
|
## CSP guide
|
|
154
208
|
|
|
155
209
|
If your app has no strict CSP, default integration works without extra setup.
|
|
156
210
|
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
- Generate nonce on server for each request.
|
|
160
|
-
- Use same nonce in:
|
|
161
|
-
- `Content-Security-Policy` header
|
|
162
|
-
- script tags loading your Angular app
|
|
163
|
-
- `cspNonce` option/input
|
|
164
|
-
- Do not generate nonce in browser.
|
|
211
|
+
For strict CSP, use a **server-generated nonce per request**.
|
|
165
212
|
|
|
166
|
-
###
|
|
213
|
+
### Recommended policy example
|
|
167
214
|
|
|
168
215
|
```http
|
|
169
216
|
default-src 'self';
|
|
170
217
|
script-src 'self' 'nonce-<dynamic>' https://embed.mycybersiara.com https://embedcdn.mycybersiara.com;
|
|
171
218
|
script-src-elem 'self' 'nonce-<dynamic>' https://embed.mycybersiara.com https://embedcdn.mycybersiara.com;
|
|
219
|
+
script-src-attr 'self' 'unsafe-inline';
|
|
172
220
|
connect-src 'self' https://embed.mycybersiara.com https://embedcdn.mycybersiara.com;
|
|
173
|
-
style-src 'self' https://embed.mycybersiara.com https://mycybersiara.com https://fonts.googleapis.com https://cdnjs.cloudflare.com;
|
|
221
|
+
style-src 'self' 'nonce-<dynamic>' https://embed.mycybersiara.com https://mycybersiara.com https://fonts.googleapis.com https://cdnjs.cloudflare.com;
|
|
222
|
+
style-src-elem 'self' 'nonce-<dynamic>' https://embed.mycybersiara.com https://mycybersiara.com https://fonts.googleapis.com https://cdnjs.cloudflare.com;
|
|
223
|
+
style-src-attr 'self' 'unsafe-inline';
|
|
174
224
|
font-src 'self' https://fonts.gstatic.com https://mycybersiara.com https://cdnjs.cloudflare.com data:;
|
|
175
225
|
img-src 'self' data: https://embed.mycybersiara.com https://embedcdn.mycybersiara.com https://mycybersiara.com;
|
|
176
226
|
```
|
|
177
227
|
|
|
178
|
-
### Compatibility policy (easier integration, weaker security)
|
|
179
|
-
|
|
180
|
-
Use only when customer policy allows `'unsafe-inline'`:
|
|
181
|
-
|
|
182
|
-
```ts
|
|
183
|
-
import { getSiaraShieldCspPolicy } from 'siarashield_workspace';
|
|
184
|
-
|
|
185
|
-
const csp = getSiaraShieldCspPolicy({
|
|
186
|
-
includeUnsafeInlineScript: true,
|
|
187
|
-
includeUnsafeInlineStyle: true,
|
|
188
|
-
});
|
|
189
|
-
```
|
|
190
|
-
|
|
191
228
|
## Script loading behavior
|
|
192
229
|
|
|
193
|
-
By default (`loadJQuery: true`) package loads
|
|
194
|
-
|
|
230
|
+
By default (`loadJQuery: true`) the package loads:
|
|
195
231
|
- `https://embedcdn.mycybersiara.com/capcha-temple/js/jquery.min.js` (fallback when jQuery not already present)
|
|
196
232
|
- `https://embedcdn.mycybersiara.com/CaptchaFormate/CaptchaResources.js`
|
|
197
233
|
- `https://embed.mycybersiara.com/CaptchaFormate/SiaraShield_Validation.js`
|
|
@@ -200,18 +236,6 @@ Most users should **not** add these script tags manually.
|
|
|
200
236
|
|
|
201
237
|
If your app already has jQuery, set `[loadJQuery]="false"` (or `loadJQuery: false` in function API).
|
|
202
238
|
|
|
203
|
-
## Advanced validation options
|
|
204
|
-
|
|
205
|
-
`checkCaptchaAsync(...)` and `checkSiaraShieldCaptchaAsync(...)` support optional tuning:
|
|
206
|
-
|
|
207
|
-
- `timeoutMs`
|
|
208
|
-
- `pollIntervalMs`
|
|
209
|
-
- `beforeCheckDelayMs`
|
|
210
|
-
- `retryOnFalseMs` (default `0`)
|
|
211
|
-
- `falseResultTokenWaitMs` (default `900`)
|
|
212
|
-
|
|
213
|
-
Default behavior is tuned to avoid requiring a second user click when token arrives slightly after first response.
|
|
214
|
-
|
|
215
239
|
## Quick troubleshooting
|
|
216
240
|
|
|
217
241
|
- Captcha not visible:
|
|
@@ -223,16 +247,6 @@ Default behavior is tuned to avoid requiring a second user click when token arri
|
|
|
223
247
|
- Ensure CSP allows required hosts and nonce.
|
|
224
248
|
- Token not available immediately:
|
|
225
249
|
- Use async check methods (`checkCaptchaAsync` / `checkSiaraShieldCaptchaAsync`).
|
|
226
|
-
- CSP errors:
|
|
227
|
-
- Confirm same server-generated nonce in header, script tags, and `cspNonce`.
|
|
228
|
-
|
|
229
|
-
## Final checklist
|
|
230
|
-
|
|
231
|
-
- Public key in frontend, private key only in backend.
|
|
232
|
-
- Submit button contains `CaptchaSubmit`.
|
|
233
|
-
- Captcha check runs before submit API call.
|
|
234
|
-
- Only one integration style is used per page.
|
|
235
|
-
- CSP nonce is wired correctly for strict CSP deployments.
|
|
236
250
|
|
|
237
251
|
## Build and pack (maintainers)
|
|
238
252
|
|