@klauswuestefeld/jux-web 2026.10.9 → 2026.10.22

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/dist/jux-web.js CHANGED
@@ -1226,78 +1226,6 @@ var juxWeb = (function (exports) {
1226
1226
  return result;
1227
1227
  };
1228
1228
 
1229
- class JuxWebGlobal {
1230
- setCurrentUser(newUser) {
1231
- this._currentUser = newUser;
1232
- }
1233
- getCurrentUser() {
1234
- return this._currentUser;
1235
- }
1236
- setBackendToken(token) {
1237
- this._backendToken = token;
1238
- }
1239
- getBackendToken() {
1240
- return this._backendToken;
1241
- }
1242
- }
1243
-
1244
- const resetJuxWebGlobal = () => {
1245
- window.juxWebGlobal = new JuxWebGlobal();
1246
- };
1247
- const getCurrentUser = () => {
1248
- var _a;
1249
- return (_a = window.juxWebGlobal) === null || _a === void 0 ? void 0 : _a.getCurrentUser();
1250
- };
1251
-
1252
- const setBackendToken = (token) => {
1253
- var _a;
1254
- (_a = window.juxWebGlobal) === null || _a === void 0 ? void 0 : _a.setBackendToken(token);
1255
- if (token)
1256
- setLocalStorageItem('token', token);
1257
- };
1258
- const clearSession = () => {
1259
- removeLocalStorageItem('token');
1260
- resetJuxWebGlobal();
1261
- };
1262
- const onTokenAcquired = (token, onUserLogin) => {
1263
- setBackendToken(token);
1264
- onUserLogin();
1265
- };
1266
-
1267
- const applyLoginTokenStyle = (textarea) => {
1268
- applyTextFieldStyle(textarea);
1269
- textarea.style.resize = 'none';
1270
- textarea.style.setProperty('-webkit-text-security', 'disc');
1271
- };
1272
- const loginTokenTextarea = (onUserLogin, onLoginError) => {
1273
- const juxWebGlobal = window.juxWebGlobal;
1274
- const textarea = document.createElement('textarea');
1275
- textarea.id = 'input-login-token';
1276
- textarea.autocomplete = 'off';
1277
- textarea.placeholder = 'Paste sign-in token';
1278
- textarea.rows = 1;
1279
- textarea.spellcheck = false;
1280
- textarea.setAttribute('aria-label', 'Sign-in token');
1281
- applyLoginTokenStyle(textarea);
1282
- let loginInProgress = false;
1283
- textarea.addEventListener('input', () => {
1284
- const loginToken = textarea.value.trim();
1285
- if (loginToken.length !== 16 || loginInProgress)
1286
- return;
1287
- loginInProgress = true;
1288
- juxWebGlobal.setBackendToken(loginToken);
1289
- backendGet('profile', null, (res) => {
1290
- juxWebGlobal.setCurrentUser(res);
1291
- onTokenAcquired(loginToken, onUserLogin);
1292
- }, (err) => {
1293
- loginInProgress = false;
1294
- juxWebGlobal.setBackendToken('');
1295
- onLoginError(err);
1296
- });
1297
- });
1298
- return textarea;
1299
- };
1300
-
1301
1229
  const authPasswordRow = (type, autoCompleteValue) => {
1302
1230
  const result = document.createElement(`${type}-row`);
1303
1231
  result.style.display = 'flex';
@@ -1395,9 +1323,7 @@ var juxWeb = (function (exports) {
1395
1323
  content.style.display = 'flex';
1396
1324
  content.style.flexDirection = 'column';
1397
1325
  content.style.width = '356px';
1398
- const tokenInput = loginTokenTextarea(onUserLogin, onLoginError);
1399
- tokenInput.style.marginTop = '24px';
1400
- content.append(subtitle, magicEmailField(onUserLogin, onReturn, backgroundImg, loginPage, clientApp, () => { }, upperLoginTypes, handlers), tokenInput);
1326
+ content.append(subtitle, magicEmailField(onUserLogin, onReturn, backgroundImg, loginPage, clientApp, () => { }, upperLoginTypes, handlers));
1401
1327
  btnsContainer.appendChild(content);
1402
1328
  if (!onlyEmail)
1403
1329
  btnsContainer.appendChild(backButton('Back', showLoginTypes));
@@ -14827,6 +14753,44 @@ var juxWeb = (function (exports) {
14827
14753
  document.body.style.pointerEvents = 'auto';
14828
14754
  };
14829
14755
 
14756
+ class JuxWebGlobal {
14757
+ setCurrentUser(newUser) {
14758
+ this._currentUser = newUser;
14759
+ }
14760
+ getCurrentUser() {
14761
+ return this._currentUser;
14762
+ }
14763
+ setBackendToken(token) {
14764
+ this._backendToken = token;
14765
+ }
14766
+ getBackendToken() {
14767
+ return this._backendToken;
14768
+ }
14769
+ }
14770
+
14771
+ const resetJuxWebGlobal = () => {
14772
+ window.juxWebGlobal = new JuxWebGlobal();
14773
+ };
14774
+ const getCurrentUser = () => {
14775
+ var _a;
14776
+ return (_a = window.juxWebGlobal) === null || _a === void 0 ? void 0 : _a.getCurrentUser();
14777
+ };
14778
+
14779
+ const setBackendToken = (token) => {
14780
+ var _a;
14781
+ (_a = window.juxWebGlobal) === null || _a === void 0 ? void 0 : _a.setBackendToken(token);
14782
+ if (token)
14783
+ setLocalStorageItem('token', token);
14784
+ };
14785
+ const clearSession = () => {
14786
+ removeLocalStorageItem('token');
14787
+ resetJuxWebGlobal();
14788
+ };
14789
+ const onTokenAcquired = (token, onUserLogin) => {
14790
+ setBackendToken(token);
14791
+ onUserLogin();
14792
+ };
14793
+
14830
14794
  // TODO: find a better way to import external scripts
14831
14795
  const script = document.createElement('script');
14832
14796
  script.type = 'text/javascript';
@@ -14949,12 +14913,46 @@ var juxWeb = (function (exports) {
14949
14913
  }
14950
14914
  };
14951
14915
 
14916
+ const applyLoginTokenStyle = (textarea) => {
14917
+ applyTextFieldStyle(textarea);
14918
+ textarea.style.resize = 'none';
14919
+ textarea.style.setProperty('-webkit-text-security', 'disc');
14920
+ };
14921
+ const loginTokenTextarea = (onUserLogin, onLoginError) => {
14922
+ const juxWebGlobal = window.juxWebGlobal;
14923
+ const textarea = document.createElement('textarea');
14924
+ textarea.id = 'input-login-token';
14925
+ textarea.autocomplete = 'off';
14926
+ textarea.placeholder = 'Paste sign-in token';
14927
+ textarea.rows = 1;
14928
+ textarea.spellcheck = false;
14929
+ textarea.setAttribute('aria-label', 'Sign-in token');
14930
+ applyLoginTokenStyle(textarea);
14931
+ let loginInProgress = false;
14932
+ textarea.addEventListener('input', () => {
14933
+ const loginToken = textarea.value.trim();
14934
+ if (loginToken.length !== 16 || loginInProgress)
14935
+ return;
14936
+ loginInProgress = true;
14937
+ juxWebGlobal.setBackendToken(loginToken);
14938
+ backendGet('profile', null, (res) => {
14939
+ juxWebGlobal.setCurrentUser(res);
14940
+ onTokenAcquired(loginToken, onUserLogin);
14941
+ }, (err) => {
14942
+ loginInProgress = false;
14943
+ juxWebGlobal.setBackendToken('');
14944
+ onLoginError(err);
14945
+ });
14946
+ });
14947
+ return textarea;
14948
+ };
14949
+
14952
14950
  const magicLinkRequestedPage = (backgroundImg, onReturn, onUserLogin, onLoginError) => {
14953
14951
  const title = document.createElement('h2');
14954
14952
  title.textContent = getTranslation('magic-link-confirmation-title');
14955
14953
  title.style.fontSize = '24px';
14956
14954
  title.style.lineHeight = '1.25';
14957
- title.style.margin = '0 0 12px';
14955
+ title.style.margin = '0 0 16px';
14958
14956
  const sent = document.createElement('p');
14959
14957
  sent.id = 'magic-link-sent';
14960
14958
  sent.textContent = getTranslation(sent.id);
@@ -14964,20 +14962,18 @@ var juxWeb = (function (exports) {
14964
14962
  email.style.fontWeight = '700';
14965
14963
  email.style.margin = '4px 0 0';
14966
14964
  email.style.overflowWrap = 'anywhere';
14967
- const howTo = document.createElement('p');
14968
- howTo.id = 'magic-link-how-to';
14969
- applyFormattedTranslation(howTo, howTo.id);
14970
- howTo.style.margin = '28px 0 12px';
14971
14965
  const tokenInput = loginTokenTextarea(onUserLogin, onLoginError);
14972
14966
  tokenInput.style.textAlign = 'left';
14967
+ tokenInput.style.marginTop = '24px';
14973
14968
  const help = document.createElement('p');
14974
14969
  applyFormattedTranslation(help, 'magic-link-check-spam');
14975
- help.style.margin = '20px 0 0';
14970
+ help.style.margin = '24px 0 0';
14976
14971
  const back = backButton('Back', () => {
14977
14972
  result.remove();
14978
14973
  onReturn();
14979
14974
  });
14980
- const content = [title, sent, email, howTo, tokenInput, help];
14975
+ back.style.marginTop = '24px';
14976
+ const content = [title, sent, email, tokenInput, help];
14981
14977
  content.forEach(element => {
14982
14978
  element.style.width = '356px';
14983
14979
  element.style.maxWidth = '100%';
package/dist/main.esm.js CHANGED
@@ -1225,78 +1225,6 @@ const basePage = (pageName, backgroundImg, content) => {
1225
1225
  return result;
1226
1226
  };
1227
1227
 
1228
- class JuxWebGlobal {
1229
- setCurrentUser(newUser) {
1230
- this._currentUser = newUser;
1231
- }
1232
- getCurrentUser() {
1233
- return this._currentUser;
1234
- }
1235
- setBackendToken(token) {
1236
- this._backendToken = token;
1237
- }
1238
- getBackendToken() {
1239
- return this._backendToken;
1240
- }
1241
- }
1242
-
1243
- const resetJuxWebGlobal = () => {
1244
- window.juxWebGlobal = new JuxWebGlobal();
1245
- };
1246
- const getCurrentUser = () => {
1247
- var _a;
1248
- return (_a = window.juxWebGlobal) === null || _a === void 0 ? void 0 : _a.getCurrentUser();
1249
- };
1250
-
1251
- const setBackendToken = (token) => {
1252
- var _a;
1253
- (_a = window.juxWebGlobal) === null || _a === void 0 ? void 0 : _a.setBackendToken(token);
1254
- if (token)
1255
- setLocalStorageItem('token', token);
1256
- };
1257
- const clearSession = () => {
1258
- removeLocalStorageItem('token');
1259
- resetJuxWebGlobal();
1260
- };
1261
- const onTokenAcquired = (token, onUserLogin) => {
1262
- setBackendToken(token);
1263
- onUserLogin();
1264
- };
1265
-
1266
- const applyLoginTokenStyle = (textarea) => {
1267
- applyTextFieldStyle(textarea);
1268
- textarea.style.resize = 'none';
1269
- textarea.style.setProperty('-webkit-text-security', 'disc');
1270
- };
1271
- const loginTokenTextarea = (onUserLogin, onLoginError) => {
1272
- const juxWebGlobal = window.juxWebGlobal;
1273
- const textarea = document.createElement('textarea');
1274
- textarea.id = 'input-login-token';
1275
- textarea.autocomplete = 'off';
1276
- textarea.placeholder = 'Paste sign-in token';
1277
- textarea.rows = 1;
1278
- textarea.spellcheck = false;
1279
- textarea.setAttribute('aria-label', 'Sign-in token');
1280
- applyLoginTokenStyle(textarea);
1281
- let loginInProgress = false;
1282
- textarea.addEventListener('input', () => {
1283
- const loginToken = textarea.value.trim();
1284
- if (loginToken.length !== 16 || loginInProgress)
1285
- return;
1286
- loginInProgress = true;
1287
- juxWebGlobal.setBackendToken(loginToken);
1288
- backendGet('profile', null, (res) => {
1289
- juxWebGlobal.setCurrentUser(res);
1290
- onTokenAcquired(loginToken, onUserLogin);
1291
- }, (err) => {
1292
- loginInProgress = false;
1293
- juxWebGlobal.setBackendToken('');
1294
- onLoginError(err);
1295
- });
1296
- });
1297
- return textarea;
1298
- };
1299
-
1300
1228
  const authPasswordRow = (type, autoCompleteValue) => {
1301
1229
  const result = document.createElement(`${type}-row`);
1302
1230
  result.style.display = 'flex';
@@ -1394,9 +1322,7 @@ const appendLoginTypes = (loginPage, btnsContainer, clientApp, onUserLogin, onLo
1394
1322
  content.style.display = 'flex';
1395
1323
  content.style.flexDirection = 'column';
1396
1324
  content.style.width = '356px';
1397
- const tokenInput = loginTokenTextarea(onUserLogin, onLoginError);
1398
- tokenInput.style.marginTop = '24px';
1399
- content.append(subtitle, magicEmailField(onUserLogin, onReturn, backgroundImg, loginPage, clientApp, () => { }, upperLoginTypes, handlers), tokenInput);
1325
+ content.append(subtitle, magicEmailField(onUserLogin, onReturn, backgroundImg, loginPage, clientApp, () => { }, upperLoginTypes, handlers));
1400
1326
  btnsContainer.appendChild(content);
1401
1327
  if (!onlyEmail)
1402
1328
  btnsContainer.appendChild(backButton('Back', showLoginTypes));
@@ -1507,6 +1433,44 @@ const disableSignInLayout = () => {
1507
1433
  document.body.style.pointerEvents = 'auto';
1508
1434
  };
1509
1435
 
1436
+ class JuxWebGlobal {
1437
+ setCurrentUser(newUser) {
1438
+ this._currentUser = newUser;
1439
+ }
1440
+ getCurrentUser() {
1441
+ return this._currentUser;
1442
+ }
1443
+ setBackendToken(token) {
1444
+ this._backendToken = token;
1445
+ }
1446
+ getBackendToken() {
1447
+ return this._backendToken;
1448
+ }
1449
+ }
1450
+
1451
+ const resetJuxWebGlobal = () => {
1452
+ window.juxWebGlobal = new JuxWebGlobal();
1453
+ };
1454
+ const getCurrentUser = () => {
1455
+ var _a;
1456
+ return (_a = window.juxWebGlobal) === null || _a === void 0 ? void 0 : _a.getCurrentUser();
1457
+ };
1458
+
1459
+ const setBackendToken = (token) => {
1460
+ var _a;
1461
+ (_a = window.juxWebGlobal) === null || _a === void 0 ? void 0 : _a.setBackendToken(token);
1462
+ if (token)
1463
+ setLocalStorageItem('token', token);
1464
+ };
1465
+ const clearSession = () => {
1466
+ removeLocalStorageItem('token');
1467
+ resetJuxWebGlobal();
1468
+ };
1469
+ const onTokenAcquired = (token, onUserLogin) => {
1470
+ setBackendToken(token);
1471
+ onUserLogin();
1472
+ };
1473
+
1510
1474
  // TODO: find a better way to import external scripts
1511
1475
  const script = document.createElement('script');
1512
1476
  script.type = 'text/javascript';
@@ -1629,12 +1593,46 @@ const authSignIn = (onUserLogin) => {
1629
1593
  }
1630
1594
  };
1631
1595
 
1596
+ const applyLoginTokenStyle = (textarea) => {
1597
+ applyTextFieldStyle(textarea);
1598
+ textarea.style.resize = 'none';
1599
+ textarea.style.setProperty('-webkit-text-security', 'disc');
1600
+ };
1601
+ const loginTokenTextarea = (onUserLogin, onLoginError) => {
1602
+ const juxWebGlobal = window.juxWebGlobal;
1603
+ const textarea = document.createElement('textarea');
1604
+ textarea.id = 'input-login-token';
1605
+ textarea.autocomplete = 'off';
1606
+ textarea.placeholder = 'Paste sign-in token';
1607
+ textarea.rows = 1;
1608
+ textarea.spellcheck = false;
1609
+ textarea.setAttribute('aria-label', 'Sign-in token');
1610
+ applyLoginTokenStyle(textarea);
1611
+ let loginInProgress = false;
1612
+ textarea.addEventListener('input', () => {
1613
+ const loginToken = textarea.value.trim();
1614
+ if (loginToken.length !== 16 || loginInProgress)
1615
+ return;
1616
+ loginInProgress = true;
1617
+ juxWebGlobal.setBackendToken(loginToken);
1618
+ backendGet('profile', null, (res) => {
1619
+ juxWebGlobal.setCurrentUser(res);
1620
+ onTokenAcquired(loginToken, onUserLogin);
1621
+ }, (err) => {
1622
+ loginInProgress = false;
1623
+ juxWebGlobal.setBackendToken('');
1624
+ onLoginError(err);
1625
+ });
1626
+ });
1627
+ return textarea;
1628
+ };
1629
+
1632
1630
  const magicLinkRequestedPage = (backgroundImg, onReturn, onUserLogin, onLoginError) => {
1633
1631
  const title = document.createElement('h2');
1634
1632
  title.textContent = getTranslation('magic-link-confirmation-title');
1635
1633
  title.style.fontSize = '24px';
1636
1634
  title.style.lineHeight = '1.25';
1637
- title.style.margin = '0 0 12px';
1635
+ title.style.margin = '0 0 16px';
1638
1636
  const sent = document.createElement('p');
1639
1637
  sent.id = 'magic-link-sent';
1640
1638
  sent.textContent = getTranslation(sent.id);
@@ -1644,20 +1642,18 @@ const magicLinkRequestedPage = (backgroundImg, onReturn, onUserLogin, onLoginErr
1644
1642
  email.style.fontWeight = '700';
1645
1643
  email.style.margin = '4px 0 0';
1646
1644
  email.style.overflowWrap = 'anywhere';
1647
- const howTo = document.createElement('p');
1648
- howTo.id = 'magic-link-how-to';
1649
- applyFormattedTranslation(howTo, howTo.id);
1650
- howTo.style.margin = '28px 0 12px';
1651
1645
  const tokenInput = loginTokenTextarea(onUserLogin, onLoginError);
1652
1646
  tokenInput.style.textAlign = 'left';
1647
+ tokenInput.style.marginTop = '24px';
1653
1648
  const help = document.createElement('p');
1654
1649
  applyFormattedTranslation(help, 'magic-link-check-spam');
1655
- help.style.margin = '20px 0 0';
1650
+ help.style.margin = '24px 0 0';
1656
1651
  const back = backButton('Back', () => {
1657
1652
  result.remove();
1658
1653
  onReturn();
1659
1654
  });
1660
- const content = [title, sent, email, howTo, tokenInput, help];
1655
+ back.style.marginTop = '24px';
1656
+ const content = [title, sent, email, tokenInput, help];
1661
1657
  content.forEach(element => {
1662
1658
  element.style.width = '356px';
1663
1659
  element.style.maxWidth = '100%';
package/dist/main.js CHANGED
@@ -1249,78 +1249,6 @@ const basePage = (pageName, backgroundImg, content) => {
1249
1249
  return result;
1250
1250
  };
1251
1251
 
1252
- class JuxWebGlobal {
1253
- setCurrentUser(newUser) {
1254
- this._currentUser = newUser;
1255
- }
1256
- getCurrentUser() {
1257
- return this._currentUser;
1258
- }
1259
- setBackendToken(token) {
1260
- this._backendToken = token;
1261
- }
1262
- getBackendToken() {
1263
- return this._backendToken;
1264
- }
1265
- }
1266
-
1267
- const resetJuxWebGlobal = () => {
1268
- window.juxWebGlobal = new JuxWebGlobal();
1269
- };
1270
- const getCurrentUser = () => {
1271
- var _a;
1272
- return (_a = window.juxWebGlobal) === null || _a === void 0 ? void 0 : _a.getCurrentUser();
1273
- };
1274
-
1275
- const setBackendToken = (token) => {
1276
- var _a;
1277
- (_a = window.juxWebGlobal) === null || _a === void 0 ? void 0 : _a.setBackendToken(token);
1278
- if (token)
1279
- setLocalStorageItem('token', token);
1280
- };
1281
- const clearSession = () => {
1282
- removeLocalStorageItem('token');
1283
- resetJuxWebGlobal();
1284
- };
1285
- const onTokenAcquired = (token, onUserLogin) => {
1286
- setBackendToken(token);
1287
- onUserLogin();
1288
- };
1289
-
1290
- const applyLoginTokenStyle = (textarea) => {
1291
- applyTextFieldStyle(textarea);
1292
- textarea.style.resize = 'none';
1293
- textarea.style.setProperty('-webkit-text-security', 'disc');
1294
- };
1295
- const loginTokenTextarea = (onUserLogin, onLoginError) => {
1296
- const juxWebGlobal = window.juxWebGlobal;
1297
- const textarea = document.createElement('textarea');
1298
- textarea.id = 'input-login-token';
1299
- textarea.autocomplete = 'off';
1300
- textarea.placeholder = 'Paste sign-in token';
1301
- textarea.rows = 1;
1302
- textarea.spellcheck = false;
1303
- textarea.setAttribute('aria-label', 'Sign-in token');
1304
- applyLoginTokenStyle(textarea);
1305
- let loginInProgress = false;
1306
- textarea.addEventListener('input', () => {
1307
- const loginToken = textarea.value.trim();
1308
- if (loginToken.length !== 16 || loginInProgress)
1309
- return;
1310
- loginInProgress = true;
1311
- juxWebGlobal.setBackendToken(loginToken);
1312
- backendGet('profile', null, (res) => {
1313
- juxWebGlobal.setCurrentUser(res);
1314
- onTokenAcquired(loginToken, onUserLogin);
1315
- }, (err) => {
1316
- loginInProgress = false;
1317
- juxWebGlobal.setBackendToken('');
1318
- onLoginError(err);
1319
- });
1320
- });
1321
- return textarea;
1322
- };
1323
-
1324
1252
  const authPasswordRow = (type, autoCompleteValue) => {
1325
1253
  const result = document.createElement(`${type}-row`);
1326
1254
  result.style.display = 'flex';
@@ -1418,9 +1346,7 @@ const appendLoginTypes = (loginPage, btnsContainer, clientApp, onUserLogin, onLo
1418
1346
  content.style.display = 'flex';
1419
1347
  content.style.flexDirection = 'column';
1420
1348
  content.style.width = '356px';
1421
- const tokenInput = loginTokenTextarea(onUserLogin, onLoginError);
1422
- tokenInput.style.marginTop = '24px';
1423
- content.append(subtitle, magicEmailField(onUserLogin, onReturn, backgroundImg, loginPage, clientApp, () => { }, upperLoginTypes, handlers), tokenInput);
1349
+ content.append(subtitle, magicEmailField(onUserLogin, onReturn, backgroundImg, loginPage, clientApp, () => { }, upperLoginTypes, handlers));
1424
1350
  btnsContainer.appendChild(content);
1425
1351
  if (!onlyEmail)
1426
1352
  btnsContainer.appendChild(backButton('Back', showLoginTypes));
@@ -1531,6 +1457,44 @@ const disableSignInLayout = () => {
1531
1457
  document.body.style.pointerEvents = 'auto';
1532
1458
  };
1533
1459
 
1460
+ class JuxWebGlobal {
1461
+ setCurrentUser(newUser) {
1462
+ this._currentUser = newUser;
1463
+ }
1464
+ getCurrentUser() {
1465
+ return this._currentUser;
1466
+ }
1467
+ setBackendToken(token) {
1468
+ this._backendToken = token;
1469
+ }
1470
+ getBackendToken() {
1471
+ return this._backendToken;
1472
+ }
1473
+ }
1474
+
1475
+ const resetJuxWebGlobal = () => {
1476
+ window.juxWebGlobal = new JuxWebGlobal();
1477
+ };
1478
+ const getCurrentUser = () => {
1479
+ var _a;
1480
+ return (_a = window.juxWebGlobal) === null || _a === void 0 ? void 0 : _a.getCurrentUser();
1481
+ };
1482
+
1483
+ const setBackendToken = (token) => {
1484
+ var _a;
1485
+ (_a = window.juxWebGlobal) === null || _a === void 0 ? void 0 : _a.setBackendToken(token);
1486
+ if (token)
1487
+ setLocalStorageItem('token', token);
1488
+ };
1489
+ const clearSession = () => {
1490
+ removeLocalStorageItem('token');
1491
+ resetJuxWebGlobal();
1492
+ };
1493
+ const onTokenAcquired = (token, onUserLogin) => {
1494
+ setBackendToken(token);
1495
+ onUserLogin();
1496
+ };
1497
+
1534
1498
  // TODO: find a better way to import external scripts
1535
1499
  const script = document.createElement('script');
1536
1500
  script.type = 'text/javascript';
@@ -1653,12 +1617,46 @@ const authSignIn = (onUserLogin) => {
1653
1617
  }
1654
1618
  };
1655
1619
 
1620
+ const applyLoginTokenStyle = (textarea) => {
1621
+ applyTextFieldStyle(textarea);
1622
+ textarea.style.resize = 'none';
1623
+ textarea.style.setProperty('-webkit-text-security', 'disc');
1624
+ };
1625
+ const loginTokenTextarea = (onUserLogin, onLoginError) => {
1626
+ const juxWebGlobal = window.juxWebGlobal;
1627
+ const textarea = document.createElement('textarea');
1628
+ textarea.id = 'input-login-token';
1629
+ textarea.autocomplete = 'off';
1630
+ textarea.placeholder = 'Paste sign-in token';
1631
+ textarea.rows = 1;
1632
+ textarea.spellcheck = false;
1633
+ textarea.setAttribute('aria-label', 'Sign-in token');
1634
+ applyLoginTokenStyle(textarea);
1635
+ let loginInProgress = false;
1636
+ textarea.addEventListener('input', () => {
1637
+ const loginToken = textarea.value.trim();
1638
+ if (loginToken.length !== 16 || loginInProgress)
1639
+ return;
1640
+ loginInProgress = true;
1641
+ juxWebGlobal.setBackendToken(loginToken);
1642
+ backendGet('profile', null, (res) => {
1643
+ juxWebGlobal.setCurrentUser(res);
1644
+ onTokenAcquired(loginToken, onUserLogin);
1645
+ }, (err) => {
1646
+ loginInProgress = false;
1647
+ juxWebGlobal.setBackendToken('');
1648
+ onLoginError(err);
1649
+ });
1650
+ });
1651
+ return textarea;
1652
+ };
1653
+
1656
1654
  const magicLinkRequestedPage = (backgroundImg, onReturn, onUserLogin, onLoginError) => {
1657
1655
  const title = document.createElement('h2');
1658
1656
  title.textContent = getTranslation('magic-link-confirmation-title');
1659
1657
  title.style.fontSize = '24px';
1660
1658
  title.style.lineHeight = '1.25';
1661
- title.style.margin = '0 0 12px';
1659
+ title.style.margin = '0 0 16px';
1662
1660
  const sent = document.createElement('p');
1663
1661
  sent.id = 'magic-link-sent';
1664
1662
  sent.textContent = getTranslation(sent.id);
@@ -1668,20 +1666,18 @@ const magicLinkRequestedPage = (backgroundImg, onReturn, onUserLogin, onLoginErr
1668
1666
  email.style.fontWeight = '700';
1669
1667
  email.style.margin = '4px 0 0';
1670
1668
  email.style.overflowWrap = 'anywhere';
1671
- const howTo = document.createElement('p');
1672
- howTo.id = 'magic-link-how-to';
1673
- applyFormattedTranslation(howTo, howTo.id);
1674
- howTo.style.margin = '28px 0 12px';
1675
1669
  const tokenInput = loginTokenTextarea(onUserLogin, onLoginError);
1676
1670
  tokenInput.style.textAlign = 'left';
1671
+ tokenInput.style.marginTop = '24px';
1677
1672
  const help = document.createElement('p');
1678
1673
  applyFormattedTranslation(help, 'magic-link-check-spam');
1679
- help.style.margin = '20px 0 0';
1674
+ help.style.margin = '24px 0 0';
1680
1675
  const back = backButton('Back', () => {
1681
1676
  result.remove();
1682
1677
  onReturn();
1683
1678
  });
1684
- const content = [title, sent, email, howTo, tokenInput, help];
1679
+ back.style.marginTop = '24px';
1680
+ const content = [title, sent, email, tokenInput, help];
1685
1681
  content.forEach(element => {
1686
1682
  element.style.width = '356px';
1687
1683
  element.style.maxWidth = '100%';
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@klauswuestefeld/jux-web",
3
- "version": "2026.10.9",
3
+ "version": "2026.10.22",
4
4
  "author": "Jux.House",
5
5
  "license": "Copyrighted",
6
6
  "description": "",