@quenty/secrets 7.23.0 → 7.23.2-canary.547.11ae689.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/CHANGELOG.md CHANGED
@@ -3,6 +3,29 @@
3
3
  All notable changes to this project will be documented in this file.
4
4
  See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
5
5
 
6
+ ## [7.23.2-canary.547.11ae689.0](https://github.com/Quenty/NevermoreEngine/compare/@quenty/secrets@7.23.0...@quenty/secrets@7.23.2-canary.547.11ae689.0) (2025-04-07)
7
+
8
+
9
+ ### Bug Fixes
10
+
11
+ * Add types to packages ([2374fb2](https://github.com/Quenty/NevermoreEngine/commit/2374fb2b043cfbe0e9b507b3316eec46a4e353a0))
12
+ * Bump package versions for republishing ([ba47c62](https://github.com/Quenty/NevermoreEngine/commit/ba47c62e32170bf74377b0c658c60b84306dc294))
13
+
14
+
15
+
16
+
17
+
18
+ ## [7.23.1](https://github.com/Quenty/NevermoreEngine/compare/@quenty/secrets@7.23.0...@quenty/secrets@7.23.1) (2025-04-07)
19
+
20
+
21
+ ### Bug Fixes
22
+
23
+ * Add types to packages ([2374fb2](https://github.com/Quenty/NevermoreEngine/commit/2374fb2b043cfbe0e9b507b3316eec46a4e353a0))
24
+
25
+
26
+
27
+
28
+
6
29
  # [7.23.0](https://github.com/Quenty/NevermoreEngine/compare/@quenty/secrets@7.22.5...@quenty/secrets@7.23.0) (2025-04-02)
7
30
 
8
31
  **Note:** Version bump only for package @quenty/secrets
package/LICENSE.md CHANGED
@@ -1,6 +1,6 @@
1
1
  MIT License
2
2
 
3
- Copyright (c) 2014-2024 James Onnen (Quenty)
3
+ Copyright (c) 2014-2025 James Onnen (Quenty)
4
4
 
5
5
  Permission is hereby granted, free of charge, to any person obtaining a copy
6
6
  of this software and associated documentation files (the "Software"), to deal
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@quenty/secrets",
3
- "version": "7.23.0",
3
+ "version": "7.23.2-canary.547.11ae689.0",
4
4
  "description": "Secrets storage system and API surface",
5
5
  "keywords": [
6
6
  "Roblox",
@@ -25,21 +25,21 @@
25
25
  "Quenty"
26
26
  ],
27
27
  "dependencies": {
28
- "@quenty/cmdrservice": "^13.22.0",
29
- "@quenty/datastore": "^13.20.0",
30
- "@quenty/ellipticcurvecryptography": "^1.6.0",
31
- "@quenty/loader": "^10.8.0",
32
- "@quenty/maid": "^3.4.0",
33
- "@quenty/permissionprovider": "^14.19.0",
34
- "@quenty/promise": "^10.10.1",
35
- "@quenty/remotefunctionutils": "^10.10.1",
36
- "@quenty/remoting": "^12.18.0",
37
- "@quenty/rx": "^13.17.0",
38
- "@quenty/servicebag": "^11.11.1",
39
- "@quenty/table": "^3.7.1"
28
+ "@quenty/cmdrservice": "13.22.2-canary.547.11ae689.0",
29
+ "@quenty/datastore": "13.20.2-canary.547.11ae689.0",
30
+ "@quenty/ellipticcurvecryptography": "1.6.2-canary.547.11ae689.0",
31
+ "@quenty/loader": "10.8.2-canary.547.11ae689.0",
32
+ "@quenty/maid": "3.4.2-canary.547.11ae689.0",
33
+ "@quenty/permissionprovider": "14.19.2-canary.547.11ae689.0",
34
+ "@quenty/promise": "10.10.3-canary.547.11ae689.0",
35
+ "@quenty/remotefunctionutils": "10.10.3-canary.547.11ae689.0",
36
+ "@quenty/remoting": "12.18.2-canary.547.11ae689.0",
37
+ "@quenty/rx": "13.17.2-canary.547.11ae689.0",
38
+ "@quenty/servicebag": "11.11.3-canary.547.11ae689.0",
39
+ "@quenty/table": "3.7.3-canary.547.11ae689.0"
40
40
  },
41
41
  "publishConfig": {
42
42
  "access": "public"
43
43
  },
44
- "gitHead": "e8ea56930e65322fcffc05a1556d5df988068f0b"
44
+ "gitHead": "11ae6894c9c40c596e521dc1d2a71977af63752f"
45
45
  }
@@ -10,11 +10,12 @@ local SecretsCmdrTypeUtils = require("SecretsCmdrTypeUtils")
10
10
  local SecretsServiceConstants = require("SecretsServiceConstants")
11
11
  local RemoteFunctionUtils = require("RemoteFunctionUtils")
12
12
  local Promise = require("Promise")
13
+ local _ServiceBag = require("ServiceBag")
13
14
 
14
15
  local SecretsServiceClient = {}
15
16
  SecretsServiceClient.ServiceName = "SecretsServiceClient"
16
17
 
17
- function SecretsServiceClient:Init(serviceBag)
18
+ function SecretsServiceClient:Init(serviceBag: _ServiceBag.ServiceBag)
18
19
  assert(not self._serviceBag, "Already initialized")
19
20
  self._serviceBag = assert(serviceBag, "No serviceBag")
20
21
  self._maid = Maid.new()
@@ -6,17 +6,18 @@ local require = require(script.Parent.loader).load(script)
6
6
 
7
7
  local SecretsCmdrTypeUtils = require("SecretsCmdrTypeUtils")
8
8
  local Maid = require("Maid")
9
+ local _ServiceBag = require("ServiceBag")
9
10
 
10
11
  local SecretsCommandService = {}
11
12
  SecretsCommandService.ServiceName = "SecretsCommandService"
12
13
 
13
- function SecretsCommandService:Init(serviceBag)
14
+ function SecretsCommandService:Init(serviceBag: _ServiceBag.ServiceBag)
14
15
  assert(not self._serviceBag, "Already initialized")
15
16
  self._serviceBag = assert(serviceBag, "No serviceBag")
16
17
  self._maid = Maid.new()
17
18
 
18
19
  self._cmdrService = self._serviceBag:GetService(require("CmdrService"))
19
- self._secretsService = self._serviceBag:GetService(require("SecretsService"))
20
+ self._secretsService = self._serviceBag:GetService((require :: any)("SecretsService"))
20
21
  end
21
22
 
22
23
  function SecretsCommandService:Start()
@@ -123,14 +124,14 @@ function SecretsCommandService:_registerCommands()
123
124
 
124
125
  local maxKeyLength = 6
125
126
  local maxValueLength = 5
126
- for key, value in pairs(secrets) do
127
+ for key, value in secrets do
127
128
  maxKeyLength = math.max(maxKeyLength, #key)
128
129
  maxValueLength = math.max(maxValueLength, #value)
129
130
  end
130
131
 
131
132
  local output = string.format("\n%-" .. maxKeyLength .. "s %-" .. maxValueLength .. "s", "Secret", "Value")
132
133
  output = output .. string.format("\n%s %s", string.rep("-", maxKeyLength), string.rep("-", maxValueLength))
133
- for key, value in pairs(secrets) do
134
+ for key, value in secrets do
134
135
  output = output .. string.format("\n%-" .. maxKeyLength .. "s %-" .. maxValueLength .. "s", key, value)
135
136
  end
136
137
  output = output .. string.format("\n%s %s", string.rep("-", maxKeyLength), string.rep("-", maxValueLength))
@@ -10,11 +10,12 @@ local GetRemoteFunction = require("GetRemoteFunction")
10
10
  local Promise = require("Promise")
11
11
  local Observable = require("Observable")
12
12
  local EllipticCurveCryptography = require("EllipticCurveCryptography")
13
+ local _ServiceBag = require("ServiceBag")
13
14
 
14
15
  local SecretsService = {}
15
16
  SecretsService.ServiceName = "SecretsService"
16
17
 
17
- function SecretsService:Init(serviceBag)
18
+ function SecretsService:Init(serviceBag: _ServiceBag.ServiceBag)
18
19
  assert(not self._serviceBag, "Already initialized")
19
20
  self._serviceBag = assert(serviceBag, "No serviceBag")
20
21
  self._maid = Maid.new()
@@ -39,7 +40,7 @@ end
39
40
 
40
41
  @param seed number
41
42
  ]=]
42
- function SecretsService:SetPublicKeySeed(seed)
43
+ function SecretsService:SetPublicKeySeed(seed: number)
43
44
  assert(type(seed) == "number", "Bad seed")
44
45
 
45
46
  local private, public = EllipticCurveCryptography.keypair(seed or EllipticCurveCryptography.random.random())
@@ -64,23 +65,22 @@ end
64
65
  @param secretKey string
65
66
  @return Promise<string>
66
67
  ]=]
67
- function SecretsService:PromiseSecret(secretKey)
68
+ function SecretsService:PromiseSecret(secretKey: string)
68
69
  assert(type(secretKey) == "string", "Bad secretKey")
69
70
 
70
71
  return self:_promiseSubstore():Then(function(substore)
71
- return self._maid:GivePromise(substore:Load(secretKey))
72
- :Then(function(data)
73
- if type(data) ~= "table" then
74
- return Promise.resolved(nil)
72
+ return self._maid:GivePromise(substore:Load(secretKey)):Then(function(data)
73
+ if type(data) ~= "table" then
74
+ return Promise.resolved(nil)
75
+ else
76
+ local ok, value = self:_decrypt(data)
77
+ if ok then
78
+ return value
75
79
  else
76
- local ok, value = self:_decrypt(data)
77
- if ok then
78
- return value
79
- else
80
- return Promise.rejected(value or "Failed to decrypt result")
81
- end
80
+ return Promise.rejected(value or "Failed to decrypt result")
82
81
  end
83
- end)
82
+ end
83
+ end)
84
84
  end)
85
85
  end
86
86
 
@@ -89,23 +89,22 @@ end
89
89
 
90
90
  @return @return Promise<{string}>
91
91
  ]=]
92
- function SecretsService:PromiseAllSecrets()
92
+ function SecretsService:PromiseAllSecrets(): Promise.Promise<{ string }>
93
93
  return self:_promiseSubstore():Then(function(substore)
94
- return self._maid:GivePromise(substore:LoadAll())
95
- :Then(function(secretsList)
96
- local secretMap = {}
97
-
98
- for key, secretData in pairs(secretsList) do
99
- local ok, decrypted = self:_decrypt(secretData)
100
- if ok then
101
- secretMap[key] = decrypted
102
- else
103
- warn(string.format("[SecretsService] - Failed to decrypt %q", key))
104
- end
94
+ return self._maid:GivePromise(substore:LoadAll()):Then(function(secretsList)
95
+ local secretMap = {}
96
+
97
+ for key, secretData in secretsList do
98
+ local ok, decrypted = self:_decrypt(secretData)
99
+ if ok then
100
+ secretMap[key] = decrypted
101
+ else
102
+ warn(string.format("[SecretsService] - Failed to decrypt %q", key))
105
103
  end
104
+ end
106
105
 
107
- return secretMap
108
- end)
106
+ return secretMap
107
+ end)
109
108
  end)
110
109
  end
111
110
 
@@ -115,26 +114,29 @@ end
115
114
  @param secretKey string
116
115
  @return Observable<string>
117
116
  ]=]
118
- function SecretsService:ObserveSecret(secretKey)
117
+ function SecretsService:ObserveSecret(secretKey: string): Observable.Observable<string>
119
118
  assert(type(secretKey) == "string", "Bad secretKey")
120
119
 
121
120
  return Observable.new(function(sub)
122
121
  local maid = Maid.new()
123
122
 
124
123
  maid:GivePromise(self:_promiseSubstore():Then(function(substore)
125
- maid:GivePromise(substore:Observe(secretKey):Subscribe(function(data)
126
- if type(data) ~= "table" then
127
- sub:Fire(nil)
128
- else
129
- local ok, value = self:_decrypt(data)
130
- if ok then
131
- sub:Fire(value)
124
+ maid:GivePromise(
125
+ substore:Observe(secretKey):Subscribe(function(data)
126
+ if type(data) ~= "table" then
127
+ sub:Fire(nil)
132
128
  else
133
- -- TODO: Maybe brio instead?
134
- sub:Fail(value or "Failed to decrypt result")
129
+ local ok, value = self:_decrypt(data)
130
+ if ok then
131
+ sub:Fire(value)
132
+ else
133
+ -- TODO: Maybe brio instead?
134
+ sub:Fail(value or "Failed to decrypt result")
135
+ end
135
136
  end
136
- end
137
- end), sub:GetFailComplete())
137
+ end),
138
+ sub:GetFailComplete()
139
+ )
138
140
  end, function(err)
139
141
  sub:Fail(err or "Failed to get datastore")
140
142
  end))
@@ -148,10 +150,10 @@ end
148
150
 
149
151
  @param secretKey string
150
152
  ]=]
151
- function SecretsService:DeleteSecret(secretKey)
153
+ function SecretsService:DeleteSecret(secretKey: string): Promise.Promise<()>
152
154
  assert(type(secretKey) == "string", "Bad secretKey")
153
155
 
154
- self:_promiseSubstore():Then(function(substore)
156
+ return self:_promiseSubstore():Then(function(substore)
155
157
  substore:Delete(secretKey)
156
158
  end)
157
159
  end
@@ -162,7 +164,7 @@ end
162
164
  @param secretKey string
163
165
  @param value string
164
166
  ]=]
165
- function SecretsService:StoreSecret(secretKey, value)
167
+ function SecretsService:StoreSecret(secretKey: string, value: string)
166
168
  assert(type(secretKey) == "string", "Bad secretKey")
167
169
  assert(type(value) == "string", "Bad value")
168
170
 
@@ -174,8 +176,8 @@ function SecretsService:StoreSecret(secretKey, value)
174
176
 
175
177
  -- TODO: Encode byte array in more efficient structure for JSON
176
178
  local toStore = {
177
- encrypted = setmetatable(table.clone(encrypted), nil); -- remove metatable
178
- signature = setmetatable(table.clone(signature), nil); -- remove metatable
179
+ encrypted = setmetatable(table.clone(encrypted), nil), -- remove metatable
180
+ signature = setmetatable(table.clone(signature), nil), -- remove metatable
179
181
  }
180
182
 
181
183
  substore:Store(secretKey, toStore)
@@ -185,9 +187,9 @@ end
185
187
  --[=[
186
188
  Clears all the secrets stored in the datastore
187
189
 
188
- @return { string }
190
+ @return Promise<()>
189
191
  ]=]
190
- function SecretsService:ClearAllSecrets()
192
+ function SecretsService:ClearAllSecrets(): Promise.Promise<()>
191
193
  return self:_promiseSubstore():Then(function(substore)
192
194
  return substore:Wipe()
193
195
  end)
@@ -196,9 +198,9 @@ end
196
198
  --[=[
197
199
  Gets a list of all available secret keys for the game
198
200
 
199
- @return { string }
201
+ @return Promise<{ string }>
200
202
  ]=]
201
- function SecretsService:PromiseSecretKeyNamesList()
203
+ function SecretsService:PromiseSecretKeyNamesList(): Promise.Promise<{ string }>
202
204
  return self:_promiseSubstore():Then(function(substore)
203
205
  return substore:PromiseKeyList()
204
206
  end)
@@ -211,16 +213,24 @@ function SecretsService:_warnAboutNoPublicKeyStoredInSourceCode()
211
213
  end
212
214
  end
213
215
 
214
- function SecretsService:_getInstructions()
215
- local instructions = "[SecretsService.StoreSecret] - Security - Current private key seed is GameId, which is guessable."
216
+ function SecretsService:_getInstructions(): string
217
+ local instructions =
218
+ "[SecretsService.StoreSecret] - Security - Current private key seed is GameId, which is guessable."
216
219
  instructions = instructions .. "\n\tTIP: This is only applicable if we're storing API keys for use in here."
217
- instructions = instructions .. "\n\tTIP: If you set the private key seed in source code, attackers need source code AND datastore access"
218
- instructions = instructions .. "\n\tTIP: Call `serviceBag:GetService(require(\"SecretsService\")):SetPublicKeySeed(UNIQUE_RANDOM_NUMBER_HERE)` to suppress this warning."
220
+ instructions = instructions
221
+ .. "\n\tTIP: If you set the private key seed in source code, attackers need source code AND datastore access"
222
+ instructions = instructions
223
+ .. '\n\tTIP: Call `serviceBag:GetService(require("SecretsService")):SetPublicKeySeed(UNIQUE_RANDOM_NUMBER_HERE)` to suppress this warning.'
219
224
  instructions = instructions .. "\n\tTIP: This will invalidate previous secrets stored."
220
225
  return instructions
221
226
  end
222
227
 
223
- function SecretsService:_decrypt(data)
228
+ export type SecretsData = {
229
+ encrypted: { number },
230
+ signature: { number },
231
+ }
232
+
233
+ function SecretsService:_decrypt(data: SecretsData): (boolean?, string)
224
234
  assert(type(data) == "table", "Bad data")
225
235
  assert(data.encrypted ~= nil, "Bad data.encrypted")
226
236
  assert(data.signature ~= nil, "Bad data.signature")
@@ -2,8 +2,6 @@
2
2
  @class SecretsCmdrTypeUtils
3
3
  ]=]
4
4
 
5
- local require = require(script.Parent.loader).load(script)
6
-
7
5
  local SecretsCmdrTypeUtils = {}
8
6
 
9
7
  function SecretsCmdrTypeUtils.registerSecretKeyTypes(cmdr, secretsService)
@@ -19,7 +17,7 @@ end
19
17
  function SecretsCmdrTypeUtils.makeSecretKeyType(cmdr, secretsService, isRequired)
20
18
  return {
21
19
  Transform = function(text)
22
- local secretNames = secretsService:PromiseSecretKeyNamesList():Wait();
20
+ local secretNames = secretsService:PromiseSecretKeyNamesList():Wait()
23
21
  local list
24
22
  if not isRequired then
25
23
  list = table.clone(secretNames)