react-native-secreton 2.2.1 → 2.3.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/README.md CHANGED
@@ -1,9 +1,12 @@
1
1
  # react-native-secreton
2
- Config secret variables for React Native apps
2
+ A library for managing **secret environment variables** in React Native apps.
3
+ Supports integration with **Consul** and **Vault** to securely retrieve configurations.
3
4
 
4
5
  ## Installation
5
- ```sh
6
+ ```bash
6
7
  npm install react-native-secreton
8
+ # or
9
+ yarn add react-native-secreton
7
10
  ```
8
11
 
9
12
  ## Generate secret key
@@ -15,7 +18,7 @@ openssl rand -hex 32
15
18
  ## Setup
16
19
  Link the library:
17
20
  ```
18
- $ react-native link react-native-config
21
+ $ react-native link react-native-secreton
19
22
  ```
20
23
 
21
24
  - Manual Link (Android)
@@ -39,6 +42,30 @@ $ react-native link react-native-config
39
42
  + pod 'react-native-secreton', :path => '../node_modules/react-native-secreton'
40
43
  ```
41
44
 
45
+ ## Usage Examples
46
+
47
+ ### Using Consul
48
+ ```bash
49
+ export ENV_SECRET_KEY=my-secret
50
+ export FETCH_ENV=consul
51
+ export CONSUL_ADDR=http://consul.mycompany.com:8500
52
+ export CONSUL_PATH=mobile/myapp
53
+ export CONSUL_TOKEN=abcd1234
54
+
55
+ rn-secreton-cli .env
56
+ ```
57
+
58
+ ### Using Vault
59
+ ```bash
60
+ export ENV_SECRET_KEY=my-secret
61
+ export FETCH_ENV=vault
62
+ export VAULT_ADDR=http://vault.mycompany.com:8200
63
+ export VAULT_PATH=secret/data/mobile/myapp
64
+ export VAULT_TOKEN=abcd1234
65
+
66
+ rn-secreton-cli .env
67
+ ```
68
+
42
69
  ## Native Usage
43
70
 
44
71
  ### Android
@@ -63,8 +90,6 @@ Then in Xcode build settings:
63
90
  2. Use on native iOS (Objective‑C/Swift)
64
91
  ```objective‑c
65
92
  let apiKey = ProcessInfo.processInfo.environment["GEO_APK_API_KEY"]
66
-
67
- or
68
-
93
+ # or
69
94
  let apiKey = Bundle.main.object(forInfoDictionaryKey: "GEO_APK_API_KEY") as? String
70
95
  ```
@@ -72,10 +72,15 @@ ext.decryptValue = { String encrypted, String secretKey ->
72
72
  proc.waitFor()
73
73
 
74
74
  if (proc.exitValue() != 0) {
75
- throw new RuntimeException(proc.err.text)
75
+ throw new RuntimeException("❌ OpenSSL decrypt failed: ${proc.err.text}")
76
76
  }
77
77
 
78
- return proc.in.text.trim()
78
+ def output = proc.in.text.trim()
79
+ if (!output) {
80
+ throw new RuntimeException("❌ Decryption returned empty value")
81
+ }
82
+
83
+ return output
79
84
  }
80
85
 
81
86
  ext.loadAndDecryptEnv = { appProject ->
@@ -97,8 +102,11 @@ ext.loadAndDecryptEnv = { appProject ->
97
102
  def envMap = loadEnvFile(envFile)
98
103
  envMap.each { k, v ->
99
104
  def value = v
100
- if (v instanceof String && v.startsWith("enc:")) {
101
- value = decryptValue(v.substring(4), secretKey)
105
+ if (v instanceof String && v.startsWith("secreton:")) {
106
+ value = decryptValue(v.substring(9), secretKey)
107
+ }
108
+ if (value == null) {
109
+ throw new RuntimeException("❌ Failed to resolve env ${k}")
102
110
  }
103
111
  appProject.ext.env[k] = value
104
112
  }
@@ -3,21 +3,54 @@ package com.secreton
3
3
  import com.facebook.react.bridge.ReactApplicationContext
4
4
  import com.facebook.react.module.annotations.ReactModule
5
5
 
6
+ import android.util.Base64
7
+ import javax.crypto.Cipher
8
+ import javax.crypto.SecretKeyFactory
9
+ import javax.crypto.spec.IvParameterSpec
10
+ import javax.crypto.spec.PBEKeySpec
11
+ import javax.crypto.spec.SecretKeySpec
12
+
6
13
  @ReactModule(name = SecretonModule.NAME)
7
14
  class SecretonModule(reactContext: ReactApplicationContext) :
8
15
  NativeSecretonSpec(reactContext) {
9
16
 
17
+ companion object {
18
+ const val NAME = "Secreton"
19
+ }
20
+
10
21
  override fun getName(): String {
11
22
  return NAME
12
23
  }
13
24
 
14
- // Example method
15
- // See https://reactnative.dev/docs/native-modules-android
16
- override fun multiply(a: Double, b: Double): Double {
17
- return a * b
25
+ override fun encrypt(value: String, key: String): String {
26
+ val salt = ByteArray(16)
27
+ val iv = ByteArray(16)
28
+
29
+ val factory = SecretKeyFactory.getInstance("PBKDF2WithHmacSHA256")
30
+ val spec = PBEKeySpec(key.toCharArray(), salt, 100000, 256)
31
+ val tmp = factory.generateSecret(spec)
32
+ val secretKey = SecretKeySpec(tmp.encoded, "AES")
33
+
34
+ val cipher = Cipher.getInstance("AES/CBC/PKCS7Padding")
35
+ cipher.init(Cipher.ENCRYPT_MODE, secretKey, IvParameterSpec(iv))
36
+
37
+ val encrypted = cipher.doFinal(value.toByteArray())
38
+ return Base64.encodeToString(encrypted, Base64.NO_WRAP)
18
39
  }
19
40
 
20
- companion object {
21
- const val NAME = "Secreton"
41
+ override fun decrypt(encrypted: String, key: String): String {
42
+ val salt = ByteArray(16)
43
+ val iv = ByteArray(16)
44
+
45
+ val factory = SecretKeyFactory.getInstance("PBKDF2WithHmacSHA256")
46
+ val spec = PBEKeySpec(key.toCharArray(), salt, 100000, 256)
47
+ val tmp = factory.generateSecret(spec)
48
+ val secretKey = SecretKeySpec(tmp.encoded, "AES")
49
+
50
+ val cipher = Cipher.getInstance("AES/CBC/PKCS7Padding")
51
+ cipher.init(Cipher.DECRYPT_MODE, secretKey, IvParameterSpec(iv))
52
+
53
+ val decoded = Base64.decode(encrypted, Base64.NO_WRAP)
54
+ return String(cipher.doFinal(decoded))
22
55
  }
23
56
  }
@@ -25,7 +25,7 @@ class SecretonPackage : BaseReactPackage() {
25
25
  false, // canOverrideExistingModule
26
26
  false, // needsEagerInit
27
27
  false, // isCxxModule
28
- true // isTurboModule
28
+ true // isTurboModule
29
29
  )
30
30
  moduleInfos
31
31
  }
@@ -5,6 +5,10 @@ export function encrypt(value, key) {
5
5
  const cmd = `printf "%s" "${value}" | openssl enc -aes-256-cbc -a -A -salt -pbkdf2 -iter 100000 -pass pass:${key}`;
6
6
  return execSync(cmd).toString().trim();
7
7
  }
8
+ export function decrypt(encrypted, key) {
9
+ const cmd = `printf "%s" "${encrypted}" | openssl enc -aes-256-cbc -a -A -d -salt -pbkdf2 -iter 100000 -pass pass:${key}`;
10
+ return execSync(cmd).toString().trim();
11
+ }
8
12
  export function readExistingEnv(envFile) {
9
13
  if (!fs.existsSync(envFile))
10
14
  return new Set();
@@ -60,7 +64,7 @@ export async function generateEnv(options) {
60
64
  }
61
65
  const newLines = entries
62
66
  .filter(({ key }) => !existingKeys.has(key))
63
- .map(({ key, value }) => `${key}=enc:${encrypt(value, secretKey)}`);
67
+ .map(({ key, value }) => `${key}=secreton:${encrypt(value, secretKey)}`);
64
68
  if (newLines.length === 0) {
65
69
  console.log('ℹ️ [Node] Secreton no new env keys to add');
66
70
  return;
package/ios/Secreton.mm CHANGED
@@ -1,21 +1,76 @@
1
1
  #import "Secreton.h"
2
2
 
3
+ #import <CommonCrypto/CommonCrypto.h>
4
+
3
5
  @implementation Secreton
4
- - (NSNumber *)multiply:(double)a b:(double)b {
5
- NSNumber *result = @(a * b);
6
6
 
7
- return result;
7
+ + (NSString *)moduleName
8
+ {
9
+ return @"Secreton";
8
10
  }
9
11
 
10
- - (std::shared_ptr<facebook::react::TurboModule>)getTurboModule:
11
- (const facebook::react::ObjCTurboModule::InitParams &)params
12
+ #pragma mark - TurboModule methods
13
+
14
+ - (NSString *)encrypt:(NSString *)value key:(NSString *)key
12
15
  {
13
- return std::make_shared<facebook::react::NativeSecretonSpecJSI>(params);
16
+ return [self aes:kCCEncrypt value:value key:key];
14
17
  }
15
18
 
16
- + (NSString *)moduleName
19
+ - (NSString *)decrypt:(NSString *)value key:(NSString *)key
17
20
  {
18
- return @"Secreton";
21
+ return [self aes:kCCDecrypt value:value key:key];
22
+ }
23
+
24
+ #pragma mark - AES core
25
+
26
+ - (NSString *)aes:(CCOperation)operation
27
+ value:(NSString *)value
28
+ key:(NSString *)key
29
+ {
30
+ NSData *data = [value dataUsingEncoding:NSUTF8StringEncoding];
31
+
32
+ // FIX: key 32 byte (AES-256)
33
+ NSMutableData *keyData = [NSMutableData dataWithLength:kCCKeySizeAES256];
34
+ NSData *rawKey = [key dataUsingEncoding:NSUTF8StringEncoding];
35
+ NSUInteger copyLen = MIN(rawKey.length, kCCKeySizeAES256);
36
+ memcpy(keyData.mutableBytes, rawKey.bytes, copyLen);
37
+
38
+ size_t outLength = 0;
39
+ NSMutableData *outData = [NSMutableData dataWithLength:data.length + kCCBlockSizeAES128];
40
+
41
+ CCCryptorStatus status = CCCrypt(
42
+ operation,
43
+ kCCAlgorithmAES,
44
+ kCCOptionPKCS7Padding,
45
+ keyData.bytes,
46
+ kCCKeySizeAES256,
47
+ NULL, // IV = zero (compat Swift)
48
+ data.bytes,
49
+ data.length,
50
+ outData.mutableBytes,
51
+ outData.length,
52
+ &outLength
53
+ );
54
+
55
+ if (status != kCCSuccess) {
56
+ return nil;
57
+ }
58
+
59
+ outData.length = outLength;
60
+
61
+ if (operation == kCCEncrypt) {
62
+ return [outData base64EncodedStringWithOptions:0];
63
+ }
64
+
65
+ return [[NSString alloc] initWithData:outData encoding:NSUTF8StringEncoding];
66
+ }
67
+
68
+ #pragma mark - TurboModule binding
69
+
70
+ - (std::shared_ptr<facebook::react::TurboModule>)getTurboModule:
71
+ (const facebook::react::ObjCTurboModule::InitParams &)params
72
+ {
73
+ return std::make_shared<facebook::react::NativeSecretonSpecJSI>(params);
19
74
  }
20
75
 
21
76
  @end
@@ -1 +1 @@
1
- {"version":3,"names":["TurboModuleRegistry","getEnforcing"],"sourceRoot":"../../src","sources":["NativeSecreton.ts"],"mappings":";;AAAA,SAASA,mBAAmB,QAA0B,cAAc;AAMpE,eAAeA,mBAAmB,CAACC,YAAY,CAAO,UAAU,CAAC","ignoreList":[]}
1
+ {"version":3,"names":["TurboModuleRegistry","getEnforcing"],"sourceRoot":"../../src","sources":["NativeSecreton.ts"],"mappings":";;AAAA,SAASA,mBAAmB,QAA0B,cAAc;AAOpE,eAAeA,mBAAmB,CAACC,YAAY,CAAO,UAAU,CAAC","ignoreList":[]}
@@ -7,6 +7,10 @@ export function encrypt(value, key) {
7
7
  const cmd = `printf "%s" "${value}" | openssl enc -aes-256-cbc -a -A -salt -pbkdf2 -iter 100000 -pass pass:${key}`;
8
8
  return execSync(cmd).toString().trim();
9
9
  }
10
+ export function decrypt(encrypted, key) {
11
+ const cmd = `printf "%s" "${encrypted}" | openssl enc -aes-256-cbc -a -A -d -salt -pbkdf2 -iter 100000 -pass pass:${key}`;
12
+ return execSync(cmd).toString().trim();
13
+ }
10
14
  export function readExistingEnv(envFile) {
11
15
  if (!fs.existsSync(envFile)) return new Set();
12
16
  const content = fs.readFileSync(envFile, 'utf8');
@@ -67,7 +71,7 @@ export async function generateEnv(options) {
67
71
  }) => !existingKeys.has(key)).map(({
68
72
  key,
69
73
  value
70
- }) => `${key}=enc:${encrypt(value, secretKey)}`);
74
+ }) => `${key}=secreton:${encrypt(value, secretKey)}`);
71
75
  if (newLines.length === 0) {
72
76
  console.log('ℹ️ [Node] Secreton no new env keys to add');
73
77
  return;
@@ -1 +1 @@
1
- {"version":3,"names":["path","fs","execSync","encrypt","value","key","cmd","toString","trim","readExistingEnv","envFile","existsSync","Set","content","readFileSync","split","map","line","filter","Boolean","startsWith","length","fetchConsul","addr","token","headers","res","fetch","ok","Error","data","json","item","Value","Key","replace","Buffer","from","fetchVault","Object","entries","String","generateEnv","options","secretKey","fetchEnv","fileName","basename","existingKeys","vault","consul","newLines","has","console","log","appendFileSync","join"],"sourceRoot":"../../src","sources":["NodeSecreton.ts"],"mappings":"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","ignoreList":[]}
1
+ {"version":3,"names":["path","fs","execSync","encrypt","value","key","cmd","toString","trim","decrypt","encrypted","readExistingEnv","envFile","existsSync","Set","content","readFileSync","split","map","line","filter","Boolean","startsWith","length","fetchConsul","addr","token","headers","res","fetch","ok","Error","data","json","item","Value","Key","replace","Buffer","from","fetchVault","Object","entries","String","generateEnv","options","secretKey","fetchEnv","fileName","basename","existingKeys","vault","consul","newLines","has","console","log","appendFileSync","join"],"sourceRoot":"../../src","sources":["NodeSecreton.ts"],"mappings":"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","ignoreList":[]}
@@ -1,7 +1,10 @@
1
1
  "use strict";
2
2
 
3
3
  import Secreton from "./NativeSecreton.js";
4
- export function multiply(a, b) {
5
- return Secreton.multiply(a, b);
4
+ export function encrypt(value, key) {
5
+ return Secreton.encrypt(value, key);
6
+ }
7
+ export function decrypt(encrypted, key) {
8
+ return Secreton.decrypt(encrypted, key);
6
9
  }
7
10
  //# sourceMappingURL=index.js.map
@@ -1 +1 @@
1
- {"version":3,"names":["Secreton","multiply","a","b"],"sourceRoot":"../../src","sources":["index.tsx"],"mappings":";;AAAA,OAAOA,QAAQ,MAAM,qBAAkB;AAEvC,OAAO,SAASC,QAAQA,CAACC,CAAS,EAAEC,CAAS,EAAU;EACrD,OAAOH,QAAQ,CAACC,QAAQ,CAACC,CAAC,EAAEC,CAAC,CAAC;AAChC","ignoreList":[]}
1
+ {"version":3,"names":["Secreton","encrypt","value","key","decrypt","encrypted"],"sourceRoot":"../../src","sources":["index.tsx"],"mappings":";;AAAA,OAAOA,QAAQ,MAAM,qBAAkB;AAEvC,OAAO,SAASC,OAAOA,CAACC,KAAa,EAAEC,GAAW,EAAU;EAC1D,OAAOH,QAAQ,CAACC,OAAO,CAACC,KAAK,EAAEC,GAAG,CAAC;AACrC;AAEA,OAAO,SAASC,OAAOA,CAACC,SAAiB,EAAEF,GAAW,EAAU;EAC9D,OAAOH,QAAQ,CAACI,OAAO,CAACC,SAAS,EAAEF,GAAG,CAAC;AACzC","ignoreList":[]}
@@ -1,6 +1,7 @@
1
1
  import { type TurboModule } from 'react-native';
2
2
  export interface Spec extends TurboModule {
3
- multiply(a: number, b: number): number;
3
+ encrypt(value: string, key: string): string;
4
+ decrypt(encrypted: string, key: string): string;
4
5
  }
5
6
  declare const _default: Spec;
6
7
  export default _default;
@@ -1 +1 @@
1
- {"version":3,"file":"NativeSecreton.d.ts","sourceRoot":"","sources":["../../../src/NativeSecreton.ts"],"names":[],"mappings":"AAAA,OAAO,EAAuB,KAAK,WAAW,EAAE,MAAM,cAAc,CAAC;AAErE,MAAM,WAAW,IAAK,SAAQ,WAAW;IACvC,QAAQ,CAAC,CAAC,EAAE,MAAM,EAAE,CAAC,EAAE,MAAM,GAAG,MAAM,CAAC;CACxC;;AAED,wBAAkE"}
1
+ {"version":3,"file":"NativeSecreton.d.ts","sourceRoot":"","sources":["../../../src/NativeSecreton.ts"],"names":[],"mappings":"AAAA,OAAO,EAAuB,KAAK,WAAW,EAAE,MAAM,cAAc,CAAC;AAErE,MAAM,WAAW,IAAK,SAAQ,WAAW;IACvC,OAAO,CAAC,KAAK,EAAE,MAAM,EAAE,GAAG,EAAE,MAAM,GAAG,MAAM,CAAC;IAC5C,OAAO,CAAC,SAAS,EAAE,MAAM,EAAE,GAAG,EAAE,MAAM,GAAG,MAAM,CAAC;CACjD;;AAED,wBAAkE"}
@@ -24,6 +24,7 @@ export interface GenerateEnvOptions {
24
24
  fetchEnv?: 'consul' | 'vault';
25
25
  }
26
26
  export declare function encrypt(value: string, key: string): string;
27
+ export declare function decrypt(encrypted: string, key: string): string;
27
28
  export declare function readExistingEnv(envFile: string): Set<string>;
28
29
  export declare function generateEnv(options: GenerateEnvOptions): Promise<void>;
29
30
  //# sourceMappingURL=NodeSecreton.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"NodeSecreton.d.ts","sourceRoot":"","sources":["../../../src/NodeSecreton.ts"],"names":[],"mappings":"AAIA,MAAM,WAAW,QAAQ;IACvB,GAAG,EAAE,MAAM,CAAC;IACZ,KAAK,EAAE,MAAM,CAAC;CACf;AAED,MAAM,WAAW,YAAY;IAC3B,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,MAAM,CAAC;IACb,KAAK,CAAC,EAAE,MAAM,CAAC;CAChB;AAED,MAAM,MAAM,QAAQ,GAAG;IACrB,GAAG,EAAE,MAAM,CAAC;IACZ,KAAK,EAAE,MAAM,GAAG,IAAI,CAAC;CACtB,CAAC;AAEF,MAAM,WAAW,WAAW;IAC1B,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,MAAM,CAAC;IACb,KAAK,EAAE,MAAM,CAAC;CACf;AAED,MAAM,WAAW,kBAAkB;IACjC,OAAO,EAAE,MAAM,CAAC;IAChB,SAAS,EAAE,MAAM,CAAC;IAClB,MAAM,CAAC,EAAE,YAAY,CAAC;IACtB,KAAK,CAAC,EAAE,WAAW,CAAC;IACpB,QAAQ,CAAC,EAAE,QAAQ,GAAG,OAAO,CAAC;CAC/B;AAED,wBAAgB,OAAO,CAAC,KAAK,EAAE,MAAM,EAAE,GAAG,EAAE,MAAM,UAGjD;AAED,wBAAgB,eAAe,CAAC,OAAO,EAAE,MAAM,GAAG,GAAG,CAAC,MAAM,CAAC,CAc5D;AAwCD,wBAAsB,WAAW,CAAC,OAAO,EAAE,kBAAkB,iBAgC5D"}
1
+ {"version":3,"file":"NodeSecreton.d.ts","sourceRoot":"","sources":["../../../src/NodeSecreton.ts"],"names":[],"mappings":"AAIA,MAAM,WAAW,QAAQ;IACvB,GAAG,EAAE,MAAM,CAAC;IACZ,KAAK,EAAE,MAAM,CAAC;CACf;AAED,MAAM,WAAW,YAAY;IAC3B,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,MAAM,CAAC;IACb,KAAK,CAAC,EAAE,MAAM,CAAC;CAChB;AAED,MAAM,MAAM,QAAQ,GAAG;IACrB,GAAG,EAAE,MAAM,CAAC;IACZ,KAAK,EAAE,MAAM,GAAG,IAAI,CAAC;CACtB,CAAC;AAEF,MAAM,WAAW,WAAW;IAC1B,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,MAAM,CAAC;IACb,KAAK,EAAE,MAAM,CAAC;CACf;AAED,MAAM,WAAW,kBAAkB;IACjC,OAAO,EAAE,MAAM,CAAC;IAChB,SAAS,EAAE,MAAM,CAAC;IAClB,MAAM,CAAC,EAAE,YAAY,CAAC;IACtB,KAAK,CAAC,EAAE,WAAW,CAAC;IACpB,QAAQ,CAAC,EAAE,QAAQ,GAAG,OAAO,CAAC;CAC/B;AAED,wBAAgB,OAAO,CAAC,KAAK,EAAE,MAAM,EAAE,GAAG,EAAE,MAAM,UAGjD;AAED,wBAAgB,OAAO,CAAC,SAAS,EAAE,MAAM,EAAE,GAAG,EAAE,MAAM,UAGrD;AAED,wBAAgB,eAAe,CAAC,OAAO,EAAE,MAAM,GAAG,GAAG,CAAC,MAAM,CAAC,CAc5D;AAwCD,wBAAsB,WAAW,CAAC,OAAO,EAAE,kBAAkB,iBAgC5D"}
@@ -1,2 +1,3 @@
1
- export declare function multiply(a: number, b: number): number;
1
+ export declare function encrypt(value: string, key: string): string;
2
+ export declare function decrypt(encrypted: string, key: string): string;
2
3
  //# sourceMappingURL=index.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/index.tsx"],"names":[],"mappings":"AAEA,wBAAgB,QAAQ,CAAC,CAAC,EAAE,MAAM,EAAE,CAAC,EAAE,MAAM,GAAG,MAAM,CAErD"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/index.tsx"],"names":[],"mappings":"AAEA,wBAAgB,OAAO,CAAC,KAAK,EAAE,MAAM,EAAE,GAAG,EAAE,MAAM,GAAG,MAAM,CAE1D;AAED,wBAAgB,OAAO,CAAC,SAAS,EAAE,MAAM,EAAE,GAAG,EAAE,MAAM,GAAG,MAAM,CAE9D"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "react-native-secreton",
3
- "version": "2.2.1",
3
+ "version": "2.3.0",
4
4
  "description": "Config secret variables for React Native apps",
5
5
  "keywords": [
6
6
  "react-native",
@@ -48,7 +48,8 @@
48
48
  "nitrogen": "nitrogen",
49
49
  "typecheck": "tsc",
50
50
  "lint": "eslint \"src/**/*.{js,ts,tsx}\"",
51
- "test": "jest",
51
+ "test": "jest -c jest.config.cjs",
52
+ "test:coverage": "jest -c jest.config.cjs --coverage --coverageDirectory=.coverage",
52
53
  "release": "release-it --only-version"
53
54
  },
54
55
  "bin": {
@@ -76,6 +77,7 @@
76
77
  "@react-native/eslint-config": "0.83.0",
77
78
  "@release-it/conventional-changelog": "^10.0.1",
78
79
  "@types/jest": "^29.5.14",
80
+ "@types/node": "^25.0.5",
79
81
  "@types/react": "^19.2.0",
80
82
  "commitlint": "^19.8.1",
81
83
  "del-cli": "^6.0.0",
@@ -90,6 +92,7 @@
90
92
  "react-native": "0.83.0",
91
93
  "react-native-builder-bob": "^0.40.17",
92
94
  "release-it": "^19.0.4",
95
+ "ts-jest": "^29.4.6",
93
96
  "turbo": "^2.5.6",
94
97
  "typescript": "^5.9.2"
95
98
  },
@@ -23,5 +23,7 @@ Pod::Spec.new do |s|
23
23
  :execution_position => :before_compile
24
24
  }
25
25
 
26
+ s.frameworks = 'Foundation', 'Security'
27
+
26
28
  install_modules_dependencies(s)
27
29
  end
@@ -1,7 +1,8 @@
1
1
  import { TurboModuleRegistry, type TurboModule } from 'react-native';
2
2
 
3
3
  export interface Spec extends TurboModule {
4
- multiply(a: number, b: number): number;
4
+ encrypt(value: string, key: string): string;
5
+ decrypt(encrypted: string, key: string): string;
5
6
  }
6
7
 
7
8
  export default TurboModuleRegistry.getEnforcing<Spec>('Secreton');
@@ -37,6 +37,11 @@ export function encrypt(value: string, key: string) {
37
37
  return execSync(cmd).toString().trim();
38
38
  }
39
39
 
40
+ export function decrypt(encrypted: string, key: string) {
41
+ const cmd = `printf "%s" "${encrypted}" | openssl enc -aes-256-cbc -a -A -d -salt -pbkdf2 -iter 100000 -pass pass:${key}`;
42
+ return execSync(cmd).toString().trim();
43
+ }
44
+
40
45
  export function readExistingEnv(envFile: string): Set<string> {
41
46
  if (!fs.existsSync(envFile)) return new Set();
42
47
 
@@ -113,7 +118,7 @@ export async function generateEnv(options: GenerateEnvOptions) {
113
118
 
114
119
  const newLines = entries
115
120
  .filter(({ key }) => !existingKeys.has(key))
116
- .map(({ key, value }) => `${key}=enc:${encrypt(value, secretKey)}`);
121
+ .map(({ key, value }) => `${key}=secreton:${encrypt(value, secretKey)}`);
117
122
 
118
123
  if (newLines.length === 0) {
119
124
  console.log('ℹ️ [Node] Secreton no new env keys to add');
package/src/index.tsx CHANGED
@@ -1,5 +1,9 @@
1
1
  import Secreton from './NativeSecreton';
2
2
 
3
- export function multiply(a: number, b: number): number {
4
- return Secreton.multiply(a, b);
3
+ export function encrypt(value: string, key: string): string {
4
+ return Secreton.encrypt(value, key);
5
+ }
6
+
7
+ export function decrypt(encrypted: string, key: string): string {
8
+ return Secreton.decrypt(encrypted, key);
5
9
  }