|
6 | 6 | import I18n from "../locale/I18n"; |
7 | 7 | import critical from "../icons/critical.svg?raw"; |
8 | 8 | import attention from "../icons/alert-circle.svg?raw"; |
9 | | -
|
| 9 | + import {FriendlyCaptchaSDK} from "@friendlycaptcha/sdk" |
10 | 10 | import {fetchServiceName, generateCodeNewUser} from "../api/index"; |
11 | 11 | import CheckBox from "../components/CheckBox.svelte"; |
12 | 12 | import Spinner from "../components/Spinner.svelte"; |
|
15 | 15 | import {domains} from "../stores/domains"; |
16 | 16 | import Cookies from "js-cookie"; |
17 | 17 | import {cookieNames} from "../constants/cookieNames"; |
| 18 | + import {isEmpty} from "../utils/utils.js"; |
18 | 19 |
|
19 | 20 | export let id; |
| 21 | +
|
20 | 22 | let emailInUse = false; |
21 | 23 | let emailForbidden = false; |
22 | 24 | let initial = true; |
23 | 25 | let showSpinner = true; |
24 | 26 | let serviceName = ""; |
25 | | -
|
26 | 27 | let agreedWithTerms = false; |
| 28 | + let captchaShowWarning = false; |
27 | 29 |
|
28 | 30 | onMount(() => { |
29 | 31 | $links.displayBackArrow = true; |
30 | 32 | $user.givenName = ""; |
31 | 33 | $user.familyName = ""; |
32 | 34 | $user.knowUser = null; |
33 | 35 | Cookies.remove(cookieNames.USERNAME); |
| 36 | + if ($conf.captchaEnabled) { |
| 37 | + const mount = document.querySelector("#captcha"); |
| 38 | + mount.addEventListener("frc:widget.complete", function(event) { |
| 39 | + captchaShowWarning = false; |
| 40 | + }); |
| 41 | +
|
| 42 | + const sdk = new FriendlyCaptchaSDK(); |
| 43 | + sdk.createWidget({ |
| 44 | + element: mount, |
| 45 | + sitekey: $conf.captchaSiteKey, |
| 46 | + startMode: "auto", |
| 47 | + language: I18n.locale, |
| 48 | + }); |
| 49 | + } |
| 50 | +
|
34 | 51 | fetchServiceName(id).then(res => { |
35 | 52 | serviceName = res.name; |
36 | 53 | showSpinner = false; |
|
39 | 56 |
|
40 | 57 | const handleNext = () => { |
41 | 58 | if (allowedNext($user.email, $user.givenName, $user.familyName, agreedWithTerms)) { |
| 59 | + const captchaResponse = document.querySelector("[name='frc-captcha-response']").value; |
| 60 | + if ($conf.captchaEnabled && isEmpty(captchaResponse) || captchaResponse === ".ACTIVATED") { |
| 61 | + captchaShowWarning = true; |
| 62 | + return; |
| 63 | + } |
42 | 64 | showSpinner = true; |
43 | | - generateCodeNewUser($user.email, $user.givenName, $user.familyName, id) |
| 65 | + generateCodeNewUser($user.email, $user.givenName, $user.familyName, id, captchaResponse) |
44 | 66 | .then(res => { |
45 | 67 | const url = res.stepup ? `/stepup/${id}?name=${encodeURIComponent(serviceName)}&explanation=${res.explanation}` : |
46 | 68 | `/code/${id}?name=${encodeURIComponent(serviceName)}&modus=cr`; |
|
72 | 94 | } |
73 | 95 |
|
74 | 96 | const allowedNext = (email, familyName, givenName, agreedWithTerms) => { |
75 | | - return validEmail(email) && familyName && givenName && agreedWithTerms && !$domains.allowedDomainNamesError |
| 97 | + return validEmail(email) && familyName && givenName && agreedWithTerms && !$domains.allowedDomainNamesError && !captchaShowWarning |
76 | 98 | }; |
77 | 99 |
|
78 | 100 | const handleEmailBlur = e => { |
|
186 | 208 | font-weight: 600; |
187 | 209 | } |
188 | 210 |
|
| 211 | + .controls { |
| 212 | + margin: 10px 0 10px 0; |
| 213 | + display: flex; |
| 214 | + flex-direction: column; |
| 215 | + gap: 10px |
| 216 | + } |
| 217 | +
|
| 218 | + #captcha { |
| 219 | + width: 335px !important; |
| 220 | + margin-top: 15px; |
| 221 | + } |
| 222 | +
|
| 223 | + :global(.frc-banner) { |
| 224 | + display: none; |
| 225 | + } |
| 226 | +
|
| 227 | +
|
189 | 228 | </style> |
190 | 229 | {#if showSpinner} |
191 | 230 | <Spinner/> |
192 | 231 | {/if} |
193 | | - |
| 232 | +<form on:keydown={(e) => e.key === 'Enter' && e.preventDefault()}> |
194 | 233 | <h2 class="header">{I18n.t("LinkFromInstitution.RequestEduIdButton.COPY")}</h2> |
195 | 234 | {#if serviceName} |
196 | 235 | <h2 class="top">{I18n.t("Login.HeaderSubTitle.COPY")}<span>{serviceName}</span></h2> |
|
207 | 246 | value={$user.email} |
208 | 247 | on:blur={handleEmailBlur}> |
209 | 248 | {#if !initial && !validEmail($user.email)} |
210 | | - <div class="error"><span class="svg">{@html critical}</span><span>{I18n.t("LinkFromInstitution.InvalidEmail.COPY")}</span></div> |
| 249 | + <div class="error"><span |
| 250 | + class="svg">{@html critical}</span><span>{I18n.t("LinkFromInstitution.InvalidEmail.COPY")}</span></div> |
211 | 251 | {/if} |
212 | 252 | {#if emailInUse} |
213 | 253 | <div class="error"> |
|
274 | 314 | {#if !initial && !$user.familyName} |
275 | 315 | <span class="error">{I18n.t("Login.RequiredAttribute.COPY", {attr: I18n.t("Profile.LastName.COPY")})}</span> |
276 | 316 | {/if} |
277 | | -<CheckBox value={agreedWithTerms} |
278 | | - className="light" |
279 | | - label={I18n.t("LinkFromInstitution.AgreeWithTerms.COPY")} |
280 | | - onChange={val => agreedWithTerms = val}/> |
281 | | -<Button disabled={showSpinner || !allowedNext($user.email, $user.familyName, $user.givenName, agreedWithTerms)} |
282 | | - href="/magic" |
283 | | - className="full" |
284 | | - label={I18n.t("LinkFromInstitution.RequestEduIdButton.COPY")} |
285 | | - onClick={handleNext}/> |
| 317 | +<div class="controls"> |
| 318 | + <CheckBox value={agreedWithTerms} |
| 319 | + className="light" |
| 320 | + label={I18n.t("LinkFromInstitution.AgreeWithTerms.COPY")} |
| 321 | + onChange={val => agreedWithTerms = val}/> |
| 322 | + <div id="captcha"></div> |
| 323 | + {#if captchaShowWarning} |
| 324 | + <span class="captcha error">{I18n.t("captcha.proveNotRobot")}</span> |
| 325 | + {/if} |
| 326 | + <Button disabled={showSpinner || !allowedNext($user.email, $user.familyName, $user.givenName, agreedWithTerms)} |
| 327 | + href="/magic" |
| 328 | + className="full" |
| 329 | + label={I18n.t("LinkFromInstitution.RequestEduIdButton.COPY")} |
| 330 | + onClick={handleNext}/> |
| 331 | +</div> |
| 332 | +</form> |
0 commit comments