@oxyhq/core 1.0.1 → 1.1.0
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/cjs/AuthManager.js +19 -9
- package/dist/cjs/CrossDomainAuth.js +2 -2
- package/dist/cjs/HttpService.js +9 -8
- package/dist/cjs/OxyServices.base.js +16 -3
- package/dist/cjs/crypto/keyManager.js +29 -24
- package/dist/cjs/crypto/polyfill.js +6 -1
- package/dist/cjs/crypto/signatureService.js +40 -31
- package/dist/cjs/i18n/index.js +36 -45
- package/dist/cjs/i18n/locales/ar-SA.json +114 -115
- package/dist/cjs/i18n/locales/ca-ES.json +114 -115
- package/dist/cjs/i18n/locales/de-DE.json +114 -115
- package/dist/cjs/i18n/locales/en-US.json +936 -936
- package/dist/cjs/i18n/locales/es-ES.json +924 -924
- package/dist/cjs/i18n/locales/fr-FR.json +114 -115
- package/dist/cjs/i18n/locales/it-IT.json +114 -115
- package/dist/cjs/i18n/locales/ja-JP.json +2 -2
- package/dist/cjs/i18n/locales/ko-KR.json +114 -115
- package/dist/cjs/i18n/locales/pt-PT.json +114 -115
- package/dist/cjs/i18n/locales/zh-CN.json +114 -115
- package/dist/cjs/mixins/OxyServices.fedcm.js +13 -41
- package/dist/cjs/mixins/OxyServices.language.js +5 -2
- package/dist/cjs/mixins/OxyServices.privacy.js +2 -1
- package/dist/cjs/mixins/OxyServices.security.js +3 -2
- package/dist/cjs/shared/utils/debugUtils.js +8 -1
- package/dist/cjs/utils/deviceManager.js +3 -1
- package/dist/cjs/utils/platform.js +3 -2
- package/dist/esm/AuthManager.js +19 -9
- package/dist/esm/CrossDomainAuth.js +2 -2
- package/dist/esm/HttpService.js +9 -8
- package/dist/esm/OxyServices.base.js +16 -3
- package/dist/esm/crypto/keyManager.js +29 -24
- package/dist/esm/crypto/polyfill.js +6 -1
- package/dist/esm/crypto/signatureService.js +40 -31
- package/dist/esm/i18n/index.js +11 -23
- package/dist/esm/i18n/locales/ar-SA.json +114 -115
- package/dist/esm/i18n/locales/ca-ES.json +114 -115
- package/dist/esm/i18n/locales/de-DE.json +114 -115
- package/dist/esm/i18n/locales/en-US.json +936 -936
- package/dist/esm/i18n/locales/es-ES.json +924 -924
- package/dist/esm/i18n/locales/fr-FR.json +114 -115
- package/dist/esm/i18n/locales/it-IT.json +114 -115
- package/dist/esm/i18n/locales/ja-JP.json +2 -2
- package/dist/esm/i18n/locales/ko-KR.json +114 -115
- package/dist/esm/i18n/locales/pt-PT.json +114 -115
- package/dist/esm/i18n/locales/zh-CN.json +114 -115
- package/dist/esm/mixins/OxyServices.fedcm.js +13 -41
- package/dist/esm/mixins/OxyServices.language.js +5 -2
- package/dist/esm/mixins/OxyServices.privacy.js +2 -1
- package/dist/esm/mixins/OxyServices.security.js +3 -2
- package/dist/esm/shared/utils/debugUtils.js +8 -1
- package/dist/esm/utils/deviceManager.js +3 -1
- package/dist/esm/utils/platform.js +3 -2
- package/dist/types/CrossDomainAuth.d.ts +2 -2
- package/dist/types/OxyServices.base.d.ts +4 -1
- package/dist/types/OxyServices.d.ts +13 -0
- package/dist/types/index.d.ts +3 -0
- package/dist/types/mixins/OxyServices.analytics.d.ts +2 -0
- package/dist/types/mixins/OxyServices.assets.d.ts +2 -0
- package/dist/types/mixins/OxyServices.auth.d.ts +2 -0
- package/dist/types/mixins/OxyServices.developer.d.ts +2 -0
- package/dist/types/mixins/OxyServices.devices.d.ts +2 -0
- package/dist/types/mixins/OxyServices.features.d.ts +2 -0
- package/dist/types/mixins/OxyServices.fedcm.d.ts +4 -2
- package/dist/types/mixins/OxyServices.karma.d.ts +2 -0
- package/dist/types/mixins/OxyServices.language.d.ts +2 -0
- package/dist/types/mixins/OxyServices.location.d.ts +2 -0
- package/dist/types/mixins/OxyServices.payment.d.ts +2 -0
- package/dist/types/mixins/OxyServices.popup.d.ts +2 -0
- package/dist/types/mixins/OxyServices.privacy.d.ts +2 -0
- package/dist/types/mixins/OxyServices.redirect.d.ts +2 -0
- package/dist/types/mixins/OxyServices.security.d.ts +2 -0
- package/dist/types/mixins/OxyServices.user.d.ts +2 -0
- package/dist/types/mixins/OxyServices.utility.d.ts +2 -0
- package/package.json +2 -3
- package/src/AuthManager.ts +25 -15
- package/src/CrossDomainAuth.ts +2 -2
- package/src/HttpService.ts +9 -8
- package/src/OxyServices.base.ts +21 -4
- package/src/OxyServices.ts +23 -2
- package/src/crypto/keyManager.ts +30 -25
- package/src/crypto/polyfill.ts +6 -1
- package/src/crypto/signatureService.ts +43 -37
- package/src/i18n/index.ts +33 -45
- package/src/index.ts +3 -0
- package/src/mixins/OxyServices.fedcm.ts +14 -44
- package/src/mixins/OxyServices.language.ts +6 -3
- package/src/mixins/OxyServices.privacy.ts +2 -1
- package/src/mixins/OxyServices.security.ts +3 -2
- package/src/shared/utils/__tests__/debugUtils.test.ts +55 -0
- package/src/shared/utils/debugUtils.ts +6 -1
- package/src/utils/deviceManager.ts +4 -2
- package/src/utils/platform.ts +3 -2
|
@@ -7,6 +7,7 @@
|
|
|
7
7
|
import { ec as EC } from 'elliptic';
|
|
8
8
|
import { isWeb, isIOS, isAndroid } from '../utils/platform';
|
|
9
9
|
import { logger } from '../utils/loggerUtils';
|
|
10
|
+
import { isDev } from '../shared/utils/debugUtils';
|
|
10
11
|
// Lazy imports for React Native specific modules
|
|
11
12
|
let SecureStore = null;
|
|
12
13
|
let ExpoCrypto = null;
|
|
@@ -41,7 +42,9 @@ const ANDROID_ACCOUNT_TYPE = 'com.oxy.account';
|
|
|
41
42
|
async function initSecureStore() {
|
|
42
43
|
if (!SecureStore) {
|
|
43
44
|
try {
|
|
44
|
-
|
|
45
|
+
// Variable indirection prevents bundlers (Vite, webpack) from statically resolving this
|
|
46
|
+
const moduleName = 'expo-secure-store';
|
|
47
|
+
SecureStore = await import(moduleName);
|
|
45
48
|
}
|
|
46
49
|
catch (error) {
|
|
47
50
|
const errorMessage = error instanceof Error ? error.message : String(error);
|
|
@@ -74,7 +77,9 @@ function isWebPlatform() {
|
|
|
74
77
|
}
|
|
75
78
|
async function initExpoCrypto() {
|
|
76
79
|
if (!ExpoCrypto) {
|
|
77
|
-
|
|
80
|
+
// Variable indirection prevents bundlers (Vite, webpack) from statically resolving this
|
|
81
|
+
const moduleName = 'expo-crypto';
|
|
82
|
+
ExpoCrypto = await import(moduleName);
|
|
78
83
|
}
|
|
79
84
|
return ExpoCrypto;
|
|
80
85
|
}
|
|
@@ -201,7 +206,7 @@ export class KeyManager {
|
|
|
201
206
|
// Update cache
|
|
202
207
|
KeyManager.cachedSharedPublicKey = publicKey;
|
|
203
208
|
KeyManager.cachedHasSharedIdentity = true;
|
|
204
|
-
if (
|
|
209
|
+
if (isDev()) {
|
|
205
210
|
logger.debug('Shared identity created successfully', { component: 'KeyManager' });
|
|
206
211
|
}
|
|
207
212
|
return publicKey;
|
|
@@ -235,7 +240,7 @@ export class KeyManager {
|
|
|
235
240
|
return publicKey;
|
|
236
241
|
}
|
|
237
242
|
catch (error) {
|
|
238
|
-
if (
|
|
243
|
+
if (isDev()) {
|
|
239
244
|
logger.warn('Failed to get shared public key', { component: 'KeyManager' }, error);
|
|
240
245
|
}
|
|
241
246
|
KeyManager.cachedSharedPublicKey = null;
|
|
@@ -268,7 +273,7 @@ export class KeyManager {
|
|
|
268
273
|
return privateKey;
|
|
269
274
|
}
|
|
270
275
|
catch (error) {
|
|
271
|
-
if (
|
|
276
|
+
if (isDev()) {
|
|
272
277
|
logger.warn('Failed to get shared private key', { component: 'KeyManager' }, error);
|
|
273
278
|
}
|
|
274
279
|
return null;
|
|
@@ -295,7 +300,7 @@ export class KeyManager {
|
|
|
295
300
|
return hasShared;
|
|
296
301
|
}
|
|
297
302
|
catch (error) {
|
|
298
|
-
if (
|
|
303
|
+
if (isDev()) {
|
|
299
304
|
logger.warn('Failed to check shared identity', { component: 'KeyManager' }, error);
|
|
300
305
|
}
|
|
301
306
|
KeyManager.cachedHasSharedIdentity = false;
|
|
@@ -338,7 +343,7 @@ export class KeyManager {
|
|
|
338
343
|
// Update cache
|
|
339
344
|
KeyManager.cachedSharedPublicKey = publicKey;
|
|
340
345
|
KeyManager.cachedHasSharedIdentity = true;
|
|
341
|
-
if (
|
|
346
|
+
if (isDev()) {
|
|
342
347
|
logger.debug('Shared identity imported successfully', { component: 'KeyManager' });
|
|
343
348
|
}
|
|
344
349
|
return publicKey;
|
|
@@ -372,12 +377,12 @@ export class KeyManager {
|
|
|
372
377
|
await store.setItemAsync(STORAGE_KEYS.SHARED_SESSION_ID, sessionId);
|
|
373
378
|
await store.setItemAsync(STORAGE_KEYS.SHARED_SESSION_TOKEN, accessToken);
|
|
374
379
|
}
|
|
375
|
-
if (
|
|
380
|
+
if (isDev()) {
|
|
376
381
|
logger.debug('Shared session stored successfully', { component: 'KeyManager' });
|
|
377
382
|
}
|
|
378
383
|
}
|
|
379
384
|
catch (error) {
|
|
380
|
-
if (
|
|
385
|
+
if (isDev()) {
|
|
381
386
|
logger.error('Failed to store shared session', error, { component: 'KeyManager' });
|
|
382
387
|
}
|
|
383
388
|
throw error;
|
|
@@ -417,7 +422,7 @@ export class KeyManager {
|
|
|
417
422
|
return { sessionId, accessToken };
|
|
418
423
|
}
|
|
419
424
|
catch (error) {
|
|
420
|
-
if (
|
|
425
|
+
if (isDev()) {
|
|
421
426
|
logger.warn('Failed to get shared session', { component: 'KeyManager' }, error);
|
|
422
427
|
}
|
|
423
428
|
return null;
|
|
@@ -447,12 +452,12 @@ export class KeyManager {
|
|
|
447
452
|
await store.deleteItemAsync(STORAGE_KEYS.SHARED_SESSION_ID);
|
|
448
453
|
await store.deleteItemAsync(STORAGE_KEYS.SHARED_SESSION_TOKEN);
|
|
449
454
|
}
|
|
450
|
-
if (
|
|
455
|
+
if (isDev()) {
|
|
451
456
|
logger.debug('Shared session cleared successfully', { component: 'KeyManager' });
|
|
452
457
|
}
|
|
453
458
|
}
|
|
454
459
|
catch (error) {
|
|
455
|
-
if (
|
|
460
|
+
if (isDev()) {
|
|
456
461
|
logger.error('Failed to clear shared session', error, { component: 'KeyManager' });
|
|
457
462
|
}
|
|
458
463
|
}
|
|
@@ -474,7 +479,7 @@ export class KeyManager {
|
|
|
474
479
|
// Check if we already have a shared identity
|
|
475
480
|
const hasShared = await KeyManager.hasSharedIdentity();
|
|
476
481
|
if (hasShared) {
|
|
477
|
-
if (
|
|
482
|
+
if (isDev()) {
|
|
478
483
|
logger.debug('Shared identity already exists, skipping migration', { component: 'KeyManager' });
|
|
479
484
|
}
|
|
480
485
|
return true;
|
|
@@ -482,20 +487,20 @@ export class KeyManager {
|
|
|
482
487
|
// Get local identity
|
|
483
488
|
const privateKey = await KeyManager.getPrivateKey();
|
|
484
489
|
if (!privateKey) {
|
|
485
|
-
if (
|
|
490
|
+
if (isDev()) {
|
|
486
491
|
logger.debug('No local identity to migrate', { component: 'KeyManager' });
|
|
487
492
|
}
|
|
488
493
|
return false;
|
|
489
494
|
}
|
|
490
495
|
// Import to shared storage
|
|
491
496
|
await KeyManager.importSharedIdentity(privateKey);
|
|
492
|
-
if (
|
|
497
|
+
if (isDev()) {
|
|
493
498
|
logger.debug('Successfully migrated local identity to shared identity', { component: 'KeyManager' });
|
|
494
499
|
}
|
|
495
500
|
return true;
|
|
496
501
|
}
|
|
497
502
|
catch (error) {
|
|
498
|
-
if (
|
|
503
|
+
if (isDev()) {
|
|
499
504
|
logger.error('Failed to migrate to shared identity', error, { component: 'KeyManager' });
|
|
500
505
|
}
|
|
501
506
|
return false;
|
|
@@ -555,7 +560,7 @@ export class KeyManager {
|
|
|
555
560
|
catch (error) {
|
|
556
561
|
// If secure store is not available, return null (no identity)
|
|
557
562
|
// This allows the app to continue functioning even if secure store fails to load
|
|
558
|
-
if (
|
|
563
|
+
if (isDev()) {
|
|
559
564
|
logger.warn('Failed to access secure store', { component: 'KeyManager' }, error);
|
|
560
565
|
}
|
|
561
566
|
return null;
|
|
@@ -582,7 +587,7 @@ export class KeyManager {
|
|
|
582
587
|
// If secure store is not available, return null (no identity)
|
|
583
588
|
// Cache null to avoid repeated failed attempts
|
|
584
589
|
KeyManager.cachedPublicKey = null;
|
|
585
|
-
if (
|
|
590
|
+
if (isDev()) {
|
|
586
591
|
logger.warn('Failed to access secure store', { component: 'KeyManager' }, error);
|
|
587
592
|
}
|
|
588
593
|
return null;
|
|
@@ -609,7 +614,7 @@ export class KeyManager {
|
|
|
609
614
|
// If we can't check, assume no identity (safer default)
|
|
610
615
|
// Cache false to avoid repeated failed attempts
|
|
611
616
|
KeyManager.cachedHasIdentity = false;
|
|
612
|
-
if (
|
|
617
|
+
if (isDev()) {
|
|
613
618
|
logger.warn('Failed to check identity', { component: 'KeyManager' }, error);
|
|
614
619
|
}
|
|
615
620
|
return false;
|
|
@@ -642,12 +647,12 @@ export class KeyManager {
|
|
|
642
647
|
if (!skipBackup) {
|
|
643
648
|
try {
|
|
644
649
|
const backupSuccess = await KeyManager.backupIdentity();
|
|
645
|
-
if (!backupSuccess &&
|
|
650
|
+
if (!backupSuccess && isDev()) {
|
|
646
651
|
logger.warn('Failed to backup identity before deletion - proceeding anyway', { component: 'KeyManager' });
|
|
647
652
|
}
|
|
648
653
|
}
|
|
649
654
|
catch (backupError) {
|
|
650
|
-
if (
|
|
655
|
+
if (isDev()) {
|
|
651
656
|
logger.warn('Failed to backup identity before deletion', { component: 'KeyManager' }, backupError);
|
|
652
657
|
}
|
|
653
658
|
}
|
|
@@ -692,7 +697,7 @@ export class KeyManager {
|
|
|
692
697
|
return true;
|
|
693
698
|
}
|
|
694
699
|
catch (error) {
|
|
695
|
-
if (
|
|
700
|
+
if (isDev()) {
|
|
696
701
|
logger.error('Failed to backup identity', error, { component: 'KeyManager' });
|
|
697
702
|
}
|
|
698
703
|
return false;
|
|
@@ -732,7 +737,7 @@ export class KeyManager {
|
|
|
732
737
|
return true;
|
|
733
738
|
}
|
|
734
739
|
catch (error) {
|
|
735
|
-
if (
|
|
740
|
+
if (isDev()) {
|
|
736
741
|
logger.error('Identity integrity check failed', error, { component: 'KeyManager' });
|
|
737
742
|
}
|
|
738
743
|
return false;
|
|
@@ -780,7 +785,7 @@ export class KeyManager {
|
|
|
780
785
|
return false;
|
|
781
786
|
}
|
|
782
787
|
catch (error) {
|
|
783
|
-
if (
|
|
788
|
+
if (isDev()) {
|
|
784
789
|
logger.error('Failed to restore identity from backup', error, { component: 'KeyManager' });
|
|
785
790
|
}
|
|
786
791
|
return false;
|
|
@@ -31,7 +31,12 @@ function getRandomBytesSync(byteCount) {
|
|
|
31
31
|
if (!expoCryptoLoadAttempted) {
|
|
32
32
|
expoCryptoLoadAttempted = true;
|
|
33
33
|
try {
|
|
34
|
-
|
|
34
|
+
// Only use require() in CJS environments (Metro/Node). In ESM (Vite/browser),
|
|
35
|
+
// crypto.getRandomValues exists natively so this code path is never reached.
|
|
36
|
+
if (typeof require !== 'undefined') {
|
|
37
|
+
const moduleName = 'expo-crypto';
|
|
38
|
+
expoCryptoModule = require(moduleName);
|
|
39
|
+
}
|
|
35
40
|
}
|
|
36
41
|
catch {
|
|
37
42
|
// expo-crypto not available — expected in non-RN environments
|
|
@@ -26,7 +26,9 @@ function isNodeJS() {
|
|
|
26
26
|
*/
|
|
27
27
|
async function initExpoCrypto() {
|
|
28
28
|
if (!ExpoCrypto) {
|
|
29
|
-
|
|
29
|
+
// Variable indirection prevents bundlers (Vite, webpack) from statically resolving this
|
|
30
|
+
const moduleName = 'expo-crypto';
|
|
31
|
+
ExpoCrypto = await import(moduleName);
|
|
30
32
|
}
|
|
31
33
|
return ExpoCrypto;
|
|
32
34
|
}
|
|
@@ -34,25 +36,29 @@ async function initExpoCrypto() {
|
|
|
34
36
|
* Compute SHA-256 hash of a string
|
|
35
37
|
*/
|
|
36
38
|
async function sha256(message) {
|
|
37
|
-
// In React Native,
|
|
38
|
-
if (isReactNative()
|
|
39
|
+
// In React Native, use expo-crypto
|
|
40
|
+
if (isReactNative()) {
|
|
39
41
|
const Crypto = await initExpoCrypto();
|
|
40
42
|
return Crypto.digestStringAsync(Crypto.CryptoDigestAlgorithm.SHA256, message);
|
|
41
43
|
}
|
|
42
44
|
// In Node.js, use Node's crypto module
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
const Crypto = await initExpoCrypto();
|
|
54
|
-
return Crypto.digestStringAsync(Crypto.CryptoDigestAlgorithm.SHA256, message);
|
|
45
|
+
if (isNodeJS()) {
|
|
46
|
+
try {
|
|
47
|
+
// eslint-disable-next-line @typescript-eslint/no-implied-eval
|
|
48
|
+
const getCrypto = new Function('return require("crypto")');
|
|
49
|
+
const nodeCrypto = getCrypto();
|
|
50
|
+
return nodeCrypto.createHash('sha256').update(message).digest('hex');
|
|
51
|
+
}
|
|
52
|
+
catch {
|
|
53
|
+
// Fall through to Web Crypto API
|
|
54
|
+
}
|
|
55
55
|
}
|
|
56
|
+
// Browser: use Web Crypto API
|
|
57
|
+
const encoder = new TextEncoder();
|
|
58
|
+
const data = encoder.encode(message);
|
|
59
|
+
const hashBuffer = await globalThis.crypto.subtle.digest('SHA-256', data);
|
|
60
|
+
const hashArray = Array.from(new Uint8Array(hashBuffer));
|
|
61
|
+
return hashArray.map(b => b.toString(16).padStart(2, '0')).join('');
|
|
56
62
|
}
|
|
57
63
|
export class SignatureService {
|
|
58
64
|
/**
|
|
@@ -60,29 +66,32 @@ export class SignatureService {
|
|
|
60
66
|
* Uses expo-crypto in React Native, crypto.randomBytes in Node.js
|
|
61
67
|
*/
|
|
62
68
|
static async generateChallenge() {
|
|
63
|
-
|
|
64
|
-
|
|
69
|
+
// In React Native, use expo-crypto
|
|
70
|
+
if (isReactNative()) {
|
|
65
71
|
const Crypto = await initExpoCrypto();
|
|
66
72
|
const randomBytes = await Crypto.getRandomBytesAsync(32);
|
|
67
73
|
return Array.from(randomBytes)
|
|
68
74
|
.map((b) => b.toString(16).padStart(2, '0'))
|
|
69
75
|
.join('');
|
|
70
76
|
}
|
|
71
|
-
// Node.js
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
return Array.from(randomBytes)
|
|
83
|
-
.map((b) => b.toString(16).padStart(2, '0'))
|
|
84
|
-
.join('');
|
|
77
|
+
// In Node.js, use Node's crypto module
|
|
78
|
+
if (isNodeJS()) {
|
|
79
|
+
try {
|
|
80
|
+
// eslint-disable-next-line @typescript-eslint/no-implied-eval
|
|
81
|
+
const getCrypto = new Function('return require("crypto")');
|
|
82
|
+
const nodeCrypto = getCrypto();
|
|
83
|
+
return nodeCrypto.randomBytes(32).toString('hex');
|
|
84
|
+
}
|
|
85
|
+
catch {
|
|
86
|
+
// Fall through to Web Crypto API
|
|
87
|
+
}
|
|
85
88
|
}
|
|
89
|
+
// Browser: use Web Crypto API
|
|
90
|
+
const bytes = new Uint8Array(32);
|
|
91
|
+
globalThis.crypto.getRandomValues(bytes);
|
|
92
|
+
return Array.from(bytes)
|
|
93
|
+
.map(b => b.toString(16).padStart(2, '0'))
|
|
94
|
+
.join('');
|
|
86
95
|
}
|
|
87
96
|
/**
|
|
88
97
|
* Hash a message using SHA-256
|
package/dist/esm/i18n/index.js
CHANGED
|
@@ -1,26 +1,14 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
// eslint-disable-next-line @typescript-eslint/no-var-requires
|
|
13
|
-
const itIT = require('./locales/it-IT.json');
|
|
14
|
-
// eslint-disable-next-line @typescript-eslint/no-var-requires
|
|
15
|
-
const ptPT = require('./locales/pt-PT.json');
|
|
16
|
-
// eslint-disable-next-line @typescript-eslint/no-var-requires
|
|
17
|
-
const jaJP = require('./locales/ja-JP.json');
|
|
18
|
-
// eslint-disable-next-line @typescript-eslint/no-var-requires
|
|
19
|
-
const koKR = require('./locales/ko-KR.json');
|
|
20
|
-
// eslint-disable-next-line @typescript-eslint/no-var-requires
|
|
21
|
-
const zhCN = require('./locales/zh-CN.json');
|
|
22
|
-
// eslint-disable-next-line @typescript-eslint/no-var-requires
|
|
23
|
-
const arSA = require('./locales/ar-SA.json');
|
|
1
|
+
import enUS from './locales/en-US.json';
|
|
2
|
+
import esES from './locales/es-ES.json';
|
|
3
|
+
import caES from './locales/ca-ES.json';
|
|
4
|
+
import frFR from './locales/fr-FR.json';
|
|
5
|
+
import deDE from './locales/de-DE.json';
|
|
6
|
+
import itIT from './locales/it-IT.json';
|
|
7
|
+
import ptPT from './locales/pt-PT.json';
|
|
8
|
+
import jaJP from './locales/ja-JP.json';
|
|
9
|
+
import koKR from './locales/ko-KR.json';
|
|
10
|
+
import zhCN from './locales/zh-CN.json';
|
|
11
|
+
import arSA from './locales/ar-SA.json';
|
|
24
12
|
const DICTS = {
|
|
25
13
|
'en': enUS,
|
|
26
14
|
'en-US': enUS,
|
|
@@ -1,120 +1,119 @@
|
|
|
1
1
|
{
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
2
|
+
"signin": {
|
|
3
|
+
"title": "تسجيل الدخول",
|
|
4
|
+
"subtitle": "سجل الدخول للمتابعة",
|
|
5
|
+
"addAccountTitle": "إضافة حساب آخر",
|
|
6
|
+
"addAccountSubtitle": "تسجيل الدخول بحساب آخر",
|
|
7
|
+
"username": {
|
|
8
|
+
"label": "اسم المستخدم",
|
|
9
|
+
"placeholder": "أدخل اسم المستخدم",
|
|
10
|
+
"helper": "3-30 حرفًا، أحرف وأرقام فقط",
|
|
11
|
+
"required": "يرجى إدخال اسم المستخدم.",
|
|
12
|
+
"minLength": "يجب أن يكون اسم المستخدم 3 أحرف على الأقل."
|
|
13
|
+
},
|
|
14
|
+
"password": {
|
|
15
|
+
"label": "كلمة المرور",
|
|
16
|
+
"placeholder": "أدخل كلمة المرور",
|
|
17
|
+
"required": "يرجى إدخال كلمة المرور.",
|
|
18
|
+
"hint": "أدخل كلمة المرور لتسجيل الدخول"
|
|
19
|
+
},
|
|
20
|
+
"actions": {
|
|
21
|
+
"continue": "متابعة",
|
|
22
|
+
"back": "رجوع",
|
|
23
|
+
"signIn": "تسجيل الدخول",
|
|
24
|
+
"verify": "التحقق",
|
|
25
|
+
"openAccountSwitcher": "التبديل إلى حساب آخر",
|
|
26
|
+
"openAccountSwitcherSubtitle": "{{count}} حسابات أخرى متاحة",
|
|
27
|
+
"openAccountSwitcherSubtitle_singular": "حساب آخر واحد متاح",
|
|
28
|
+
"openAccountSwitcherSubtitle_zero": "راجع حساباتك المحفوظة",
|
|
29
|
+
"manageAccounts": "إدارة الحسابات المحفوظة",
|
|
30
|
+
"manageAccountsSubtitle": "مراجعة الجلسات أو إزالتها أو تسجيل الخروج",
|
|
31
|
+
"loadingOtherAccounts": "جاري تحميل الحسابات الأخرى…",
|
|
32
|
+
"switchAccountFailed": "لم نتمكن من التبديل بين الحسابات. يرجى المحاولة مرة أخرى."
|
|
33
|
+
},
|
|
34
|
+
"forgotPrompt": "نسيت كلمة المرور؟",
|
|
35
|
+
"security": {
|
|
36
|
+
"dataSecure": "بياناتك مشفرة وآمنة"
|
|
37
|
+
},
|
|
38
|
+
"currentlySignedInAs": "مسجل الدخول حاليًا كـ",
|
|
39
|
+
"alreadySignedInWith": "مسجل الدخول بالفعل بـ",
|
|
40
|
+
"alreadySignedIn": "مسجل الدخول بالفعل",
|
|
41
|
+
"alreadySignedInMessage": "هذا الحساب مسجل الدخول بالفعل. المتابعة بهذا الحساب؟",
|
|
42
|
+
"continueWithAccount": "متابعة",
|
|
43
|
+
"currentAccount": "الحالي",
|
|
44
|
+
"or": "أو",
|
|
45
|
+
"viewAllAccounts": "عرض {{count}} المزيد",
|
|
46
|
+
"status": {
|
|
47
|
+
"accountSwitched": "استخدام {{name}} الآن"
|
|
48
|
+
}
|
|
13
49
|
},
|
|
14
|
-
"
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
50
|
+
"signup": {
|
|
51
|
+
"welcome": {
|
|
52
|
+
"title": "مرحبًا بك في Oxy!",
|
|
53
|
+
"subtitle": "أنشئ حسابك في خطوات قليلة",
|
|
54
|
+
"haveAccount": "لديك حساب بالفعل؟",
|
|
55
|
+
"signInCta": "تسجيل الدخول"
|
|
56
|
+
},
|
|
57
|
+
"identity": {
|
|
58
|
+
"title": "من أنت؟",
|
|
59
|
+
"subtitle": "اختر اسم المستخدم وأدخل بريدك الإلكتروني"
|
|
60
|
+
},
|
|
61
|
+
"username": {
|
|
62
|
+
"helper": "3-30 حرفًا، أحرف وأرقام فقط",
|
|
63
|
+
"required": "يرجى إدخال اسم مستخدم",
|
|
64
|
+
"minLength": "يجب أن يكون اسم المستخدم 3 أحرف على الأقل"
|
|
65
|
+
},
|
|
66
|
+
"email": {
|
|
67
|
+
"required": "يرجى إدخال عنوان بريد إلكتروني",
|
|
68
|
+
"invalid": "يرجى إدخال عنوان بريد إلكتروني صالح",
|
|
69
|
+
"helper": "لن نشارك بريدك الإلكتروني أبدًا"
|
|
70
|
+
},
|
|
71
|
+
"security": {
|
|
72
|
+
"title": "أمّن حسابك",
|
|
73
|
+
"subtitle": "أنشئ كلمة مرور قوية لحماية حسابك"
|
|
74
|
+
},
|
|
75
|
+
"password": {
|
|
76
|
+
"helper": "8 أحرف على الأقل",
|
|
77
|
+
"required": "يرجى إدخال كلمة مرور",
|
|
78
|
+
"minLength": "يجب أن تكون كلمة المرور 8 أحرف على الأقل",
|
|
79
|
+
"confirmRequired": "يرجى تأكيد كلمة المرور",
|
|
80
|
+
"mismatch": "كلمات المرور غير متطابقة",
|
|
81
|
+
"confirmHint": "أعد إدخال كلمة المرور للتأكيد"
|
|
82
|
+
},
|
|
83
|
+
"summary": {
|
|
84
|
+
"title": "أوشكت على الانتهاء!",
|
|
85
|
+
"subtitle": "راجع معلوماتك وأنشئ حسابك",
|
|
86
|
+
"sectionTitle": "معلومات الحساب",
|
|
87
|
+
"fields": {
|
|
88
|
+
"username": "اسم المستخدم",
|
|
89
|
+
"email": "البريد الإلكتروني",
|
|
90
|
+
"password": "كلمة المرور"
|
|
91
|
+
},
|
|
92
|
+
"notSet": "غير محدد",
|
|
93
|
+
"securityTip": "لمزيد من الأمان، قم بتمكين المصادقة الحيوية من إعدادات الحساب بعد إنشاء حسابك.",
|
|
94
|
+
"legalReminder": "بإنشاء حساب، فإنك توافق على شروط الخدمة وسياسة الخصوصية الخاصة بنا."
|
|
95
|
+
}
|
|
19
96
|
},
|
|
20
|
-
"
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
"alreadySignedInMessage": "هذا الحساب مسجل الدخول بالفعل. المتابعة بهذا الحساب؟",
|
|
42
|
-
"continueWithAccount": "متابعة",
|
|
43
|
-
"currentAccount": "الحالي",
|
|
44
|
-
"or": "أو",
|
|
45
|
-
"viewAllAccounts": "عرض {{count}} المزيد",
|
|
46
|
-
"status": {
|
|
47
|
-
"accountSwitched": "استخدام {{name}} الآن"
|
|
48
|
-
},
|
|
49
|
-
},
|
|
50
|
-
"signup": {
|
|
51
|
-
"welcome": {
|
|
52
|
-
"title": "مرحبًا بك في Oxy!",
|
|
53
|
-
"subtitle": "أنشئ حسابك في خطوات قليلة",
|
|
54
|
-
"haveAccount": "لديك حساب بالفعل؟",
|
|
55
|
-
"signInCta": "تسجيل الدخول"
|
|
56
|
-
},
|
|
57
|
-
"identity": {
|
|
58
|
-
"title": "من أنت؟",
|
|
59
|
-
"subtitle": "اختر اسم المستخدم وأدخل بريدك الإلكتروني"
|
|
60
|
-
},
|
|
61
|
-
"username": {
|
|
62
|
-
"helper": "3-30 حرفًا، أحرف وأرقام فقط",
|
|
63
|
-
"required": "يرجى إدخال اسم مستخدم",
|
|
64
|
-
"minLength": "يجب أن يكون اسم المستخدم 3 أحرف على الأقل"
|
|
65
|
-
},
|
|
66
|
-
"email": {
|
|
67
|
-
"required": "يرجى إدخال عنوان بريد إلكتروني",
|
|
68
|
-
"invalid": "يرجى إدخال عنوان بريد إلكتروني صالح",
|
|
69
|
-
"helper": "لن نشارك بريدك الإلكتروني أبدًا"
|
|
70
|
-
},
|
|
71
|
-
"security": {
|
|
72
|
-
"title": "أمّن حسابك",
|
|
73
|
-
"subtitle": "أنشئ كلمة مرور قوية لحماية حسابك"
|
|
74
|
-
},
|
|
75
|
-
"password": {
|
|
76
|
-
"helper": "8 أحرف على الأقل",
|
|
77
|
-
"required": "يرجى إدخال كلمة مرور",
|
|
78
|
-
"minLength": "يجب أن تكون كلمة المرور 8 أحرف على الأقل",
|
|
79
|
-
"confirmRequired": "يرجى تأكيد كلمة المرور",
|
|
80
|
-
"mismatch": "كلمات المرور غير متطابقة",
|
|
81
|
-
"confirmHint": "أعد إدخال كلمة المرور للتأكيد"
|
|
82
|
-
},
|
|
83
|
-
"summary": {
|
|
84
|
-
"title": "أوشكت على الانتهاء!",
|
|
85
|
-
"subtitle": "راجع معلوماتك وأنشئ حسابك",
|
|
86
|
-
"sectionTitle": "معلومات الحساب",
|
|
87
|
-
"fields": {
|
|
88
|
-
"username": "اسم المستخدم",
|
|
89
|
-
"email": "البريد الإلكتروني",
|
|
90
|
-
"password": "كلمة المرور"
|
|
91
|
-
},
|
|
92
|
-
"notSet": "غير محدد",
|
|
93
|
-
"securityTip": "لمزيد من الأمان، قم بتمكين المصادقة الحيوية من إعدادات الحساب بعد إنشاء حسابك.",
|
|
94
|
-
"legalReminder": "بإنشاء حساب، فإنك توافق على شروط الخدمة وسياسة الخصوصية الخاصة بنا."
|
|
95
|
-
}
|
|
96
|
-
},
|
|
97
|
-
"common": {
|
|
98
|
-
"actions": {
|
|
99
|
-
"back": "رجوع",
|
|
100
|
-
"continue": "متابعة",
|
|
101
|
-
"next": "التالي",
|
|
102
|
-
"getStarted": "ابدأ",
|
|
103
|
-
"createAccount": "إنشاء حساب",
|
|
104
|
-
"signIn": "تسجيل الدخول",
|
|
105
|
-
"verify": "التحقق",
|
|
106
|
-
"resetPassword": "إعادة تعيين كلمة المرور"
|
|
107
|
-
},
|
|
108
|
-
"links": {
|
|
109
|
-
"recoverAccount": "استعادة حسابك",
|
|
110
|
-
"signUp": "التسجيل"
|
|
111
|
-
},
|
|
112
|
-
"labels": {
|
|
113
|
-
"username": "اسم المستخدم",
|
|
114
|
-
"email": "البريد الإلكتروني",
|
|
115
|
-
"password": "كلمة المرور",
|
|
116
|
-
"confirmPassword": "تأكيد كلمة المرور"
|
|
97
|
+
"common": {
|
|
98
|
+
"actions": {
|
|
99
|
+
"back": "رجوع",
|
|
100
|
+
"continue": "متابعة",
|
|
101
|
+
"next": "التالي",
|
|
102
|
+
"getStarted": "ابدأ",
|
|
103
|
+
"createAccount": "إنشاء حساب",
|
|
104
|
+
"signIn": "تسجيل الدخول",
|
|
105
|
+
"verify": "التحقق",
|
|
106
|
+
"resetPassword": "إعادة تعيين كلمة المرور"
|
|
107
|
+
},
|
|
108
|
+
"links": {
|
|
109
|
+
"recoverAccount": "استعادة حسابك",
|
|
110
|
+
"signUp": "التسجيل"
|
|
111
|
+
},
|
|
112
|
+
"labels": {
|
|
113
|
+
"username": "اسم المستخدم",
|
|
114
|
+
"email": "البريد الإلكتروني",
|
|
115
|
+
"password": "كلمة المرور",
|
|
116
|
+
"confirmPassword": "تأكيد كلمة المرور"
|
|
117
|
+
}
|
|
117
118
|
}
|
|
118
|
-
}
|
|
119
119
|
}
|
|
120
|
-
|