secrez 2.1.7 → 2.1.9

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/.env ADDED
@@ -0,0 +1,9 @@
1
+ SECREZ_TEST_REPO_URL="git@github.com:secrez/test-repo.git"
2
+ SECREZ_TEST_SSH_KEY="-----BEGIN OPENSSH PRIVATE KEY-----
3
+ b3BlbnNzaC1rZXktdjEAAAAABG5vbmUAAAAEbm9uZQAAAAAAAAABAAAAMwAAAAtzc2gtZW
4
+ QyNTUxOQAAACB8/5MMxGmWhwKsCKzu2bC2WhWdV6BiS/c2IVMJZ10NxQAAAKBOc1L6TnNS
5
+ +gAAAAtzc2gtZWQyNTUxOQAAACB8/5MMxGmWhwKsCKzu2bC2WhWdV6BiS/c2IVMJZ10NxQ
6
+ AAAEB8z+vtbfcUQyatLMOea+l7Ku4xbFbgB1Fyzymvo0T4Vnz/kwzEaZaHAqwIrO7ZsLZa
7
+ FZ1XoGJL9zYhUwlnXQ3FAAAAF3NlY3Jlei10ZXN0QGV4YW1wbGUuY29tAQIDBAUG
8
+ -----END OPENSSH PRIVATE KEY-----"
9
+ PUBLIC_TEST_KEY="ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIHz/kwzEaZaHAqwIrO7ZsLZaFZ1XoGJL9zYhUwlnXQ3F secrez-test@example.com"
package/README.md CHANGED
@@ -152,6 +152,7 @@ Available commands:
152
152
  edit Edits a file containing a secret.
153
153
  export Export encrypted data to the OS in the current local folder
154
154
  find Find a secret.
155
+ git Checks if there is a repo and if there are conflict risks.
155
156
  help This help.
156
157
  import Import files from the OS into the current folder
157
158
  lcat Similar to a standard cat in the external fs.
@@ -369,6 +370,16 @@ Secrez is not intended to compete with password managers, so do not expect it to
369
370
 
370
371
  ## History
371
372
 
373
+ **2.1.9**
374
+
375
+ - add `<` parameter to reuse the last used path in commands (e.g., `totp <` will use the last path from previous command)
376
+ - fix deprecation warning in `execSync` by properly escaping command arguments
377
+
378
+ **2.1.8**
379
+
380
+ - add `git` command to check repository status and detect remote changes
381
+ - add git conflict detection middleware to prevent conflicts during data-changing operations
382
+
372
383
  **2.1.7**
373
384
 
374
385
  - add option `--no-export` to `export --crypto-env` to display the encrypted content in the console instead of writing it to a file
@@ -865,60 +876,7 @@ Thank you for any contributions! 😉
865
876
  ## Test coverage
866
877
 
867
878
  ```
868
- 1 passing (549ms)
869
-
870
- --------------------|---------|----------|---------|---------|--------------------------------------
871
- File | % Stmts | % Branch | % Funcs | % Lines | Uncovered Line #s
872
- --------------------|---------|----------|---------|---------|--------------------------------------
873
- All files | 18.98 | 5.52 | 20.28 | 19.04 |
874
- src | 30.39 | 14.49 | 21.05 | 30.69 |
875
- Command.js | 32.2 | 21.27 | 30.76 | 32.75 | 22-35,40-97,102,108,119,122-130
876
- PreCommand.js | 8.82 | 0 | 0 | 8.82 | 6-97
877
- cliConfig.js | 100 | 100 | 100 | 100 |
878
- src/commands | 18.27 | 4.93 | 22.16 | 18.35 |
879
- Alias.js | 8.1 | 0 | 25 | 8.21 | 62-213
880
- Bash.js | 62.5 | 0 | 33.33 | 62.5 | 11-19
881
- Cat.js | 29.67 | 17.46 | 42.85 | 29.67 | 61-93,98,110,117-142,150-169,178-220
882
- Cd.js | 17.85 | 0 | 25 | 17.85 | 28-73
883
- Conf.js | 7.79 | 0 | 10 | 7.79 | 67-500
884
- Contacts.js | 5.98 | 0 | 7.69 | 6.03 | 53-274
885
- Copy.js | 10.98 | 0 | 12.5 | 11.11 | 71-268
886
- Ds.js | 5.97 | 0 | 16.66 | 6.06 | 39-160
887
- Edit.js | 12.34 | 0 | 20 | 12.34 | 61-214
888
- Export.js | 50 | 26.92 | 50 | 50 | ...8,209,219-295,301,307-308,316-323
889
- Find.js | 7.69 | 0 | 8.33 | 7.89 | 63-211
890
- Help.js | 33.33 | 0 | 50 | 33.33 | 26-43
891
- Import.js | 6.31 | 0 | 9.09 | 6.37 | 87-496
892
- Lcat.js | 30 | 0 | 25 | 30 | 35-65
893
- Lcd.js | 17.39 | 0 | 25 | 17.39 | 30-72
894
- Lls.js | 40.9 | 9.09 | 50 | 40.9 | 49,68,74-99
895
- Lpwd.js | 38.46 | 0 | 50 | 38.46 | 15,29-38
896
- Ls.js | 5.79 | 0 | 10 | 6.15 | 46-183
897
- Mkdir.js | 22.72 | 0 | 25 | 22.72 | 27-61
898
- Mv.js | 6.52 | 0 | 16.66 | 6.66 | 46-240
899
- Paste.js | 14.89 | 0 | 25 | 14.89 | 40-131
900
- Pwd.js | 30.76 | 0 | 25 | 30.76 | 15-35
901
- Quit.js | 50 | 0 | 33.33 | 50 | 19-40
902
- Rm.js | 16 | 0 | 16.66 | 16.32 | 36-137
903
- Shell.js | 29.41 | 0 | 25 | 29.41 | 25-57
904
- Show.js | 16 | 0 | 14.28 | 16.32 | 45-145
905
- Ssh.js | 22.22 | 0 | 20 | 22.22 | 49-120
906
- Tag.js | 8.82 | 0 | 9.09 | 8.91 | 66-236
907
- Totp.js | 14.58 | 0 | 9.09 | 14.58 | 76-312
908
- Touch.js | 76 | 51.85 | 75 | 75.51 | 75,140,152-158,164,168,177,231-234
909
- Use.js | 12.9 | 0 | 25 | 12.9 | 30-85
910
- Ver.js | 50 | 0 | 33.33 | 50 | 17-28
911
- Whoami.js | 27.77 | 0 | 20 | 27.77 | 20-50
912
- index.js | 87.5 | 50 | 100 | 86.95 | 15,22,31
913
- src/prompts | 100 | 100 | 33.33 | 100 |
914
- MainPromptMock.js | 100 | 100 | 33.33 | 100 |
915
- src/utils | 14.97 | 5.46 | 10.41 | 14.75 |
916
- AliasManager.js | 5.88 | 0 | 0 | 5.88 | 3-48
917
- ContactManager.js | 6.66 | 0 | 0 | 6.66 | 3-44
918
- Fido2Client.js | 9.61 | 0 | 0 | 9.61 | 8-108
919
- HelpProto.js | 4.2 | 0 | 16.66 | 4.27 | 11-200
920
- Logger.js | 56.81 | 43.75 | 21.05 | 55.81 | ...16-29,37-57,65-69,74,84,88,93,105
921
- --------------------|---------|----------|---------|---------|--------------------------------------
879
+
922
880
  ```
923
881
 
924
882
  ## Copyright
package/coverage.report CHANGED
@@ -1,5 +1,5 @@
1
1
 
2
- > secrez@2.1.7 test /Users/francescosullo/Projects/Secrez/secrez/packages/secrez
2
+ > secrez@2.1.9 test /Users/francescosullo/Projects/Secrez/secrez/packages/secrez
3
3
  > cross-env NODE_ENV=test nyc --reporter=lcov --reporter=text mocha test/*.test.js test/**/*.test.js test/**/**/*.js --exit
4
4
 
5
5
 
@@ -29,10 +29,10 @@
29
29
  #Cat
30
30
  ✓ should return the help
31
31
  ✓ should show the content of a file
32
- ✓ should show either one or all the versions of a file (1013ms)
32
+ ✓ should show either one or all the versions of a file (1019ms)
33
33
  ✓ should throw if entry is not a file or file does not exist
34
34
  ✓ should throw if trying to cat a binary file
35
- ✓ should show the content of a Yaml file (1017ms)
35
+ ✓ should show the content of a Yaml file (1028ms)
36
36
 
37
37
  #Cd
38
38
  ✓ should return the help
@@ -51,254 +51,6 @@
51
51
 
52
52
  #Copy
53
53
  ✓ should return the help
54
- ✓ should copy a file to the clipboard (402ms)
55
- ✓ should copy a string to the clipboard (266ms)
56
- ✓ should copy a card to the clipboard (960ms)
57
- ✓ should return an error if the file does not exist or is a folder (48ms)
58
- ✓ should throw if copying to clipboard a binary files
59
-
60
- #Ds
61
- ✓ should return the help
62
- ✓ should list all datasets
63
- ✓ should create a new dataset
64
- ✓ should rename a dataset
65
- ✓ should delete a dataset
66
-
67
- #Export
68
- ✓ should return the help
69
- 1) should export a file to the current local folder
70
- ✓ should export a file encrypted only for the user itself
71
- ✓ should export a binary file to the current local folder
72
- ✓ should export an encrypted file to the current local folder
73
- ✓ should export a file and delete it after 1 second (1205ms)
74
- ✓ should return an error if the file does not exist or is a folder
75
- ✓ should export a keystore json file if a private_key exists in the entry (922ms)
76
- ✓ should export a cryptoenv file if a private_key exists in the entry
77
- ✓ should export a cryptoenv file with entire content when no private_key fields exist and user confirms
78
- ✓ should throw error when no private_key fields exist and user declines
79
- ✓ should throw error when no private_key fields exist and keystore option is used
80
- ✓ should display encrypted content in console when using crypto-env with no-export
81
-
82
- #Find
83
- ✓ should return the help
84
- ✓ should show find a string in the tree (1022ms)
85
- ✓ should find no result without parameters
86
- ✓ should skip binary files from search
87
-
88
- #Help
89
- ✓ should return the help
90
- ✓ #execAsync and format
91
- ✓ should throw if wrong command
92
- ✓ -- to complete coverage
93
-
94
- #Import
95
- ✓ should return the help
96
- ✓ should import a file in the current folder
97
- ✓ should import an encrypted file
98
- ✓ should import an encrypted file encrypted for myself
99
- ✓ should import an encrypted binary file and export it again verifying it is fine
100
- ✓ should import files recursively
101
- ✓ should read a folder and import the only text file
102
- ✓ should read a folder and import text and binary files
103
- ✓ should simulate the import of two files
104
- ✓ should move the imported file
105
- ✓ should import a backup from another software spanning the data among folders and files
106
- ✓ should import a backup from another software but saving the tags as tags
107
- ✓ should import a backup from another software using tags to prefix the paths
108
- ✓ should import using tags to prefix the paths, ignoring the tags
109
- ✓ should import from a LastPass-like csv setting the path from "grouping" and "name"
110
- ✓ should import from a json
111
- ✓ should throw importing a malformed backup
112
- ✓ should throw importing a CSV indicating wrong fields to generate the path
113
-
114
- #Lcat
115
- ✓ should return the help
116
- ✓ cat a file
117
- ✓ return en error if trying to cat a binary file
118
-
119
- #Lcd
120
- ✓ should return the help
121
- ✓ change to a folder
122
- ✓ return en error if changing to a file
123
-
124
- #Lls
125
- ✓ should return the help
126
- ✓ should list a folder
127
- ✓ return en error if lls-ing a not existing path
128
- ✓ return a message if no files are found
129
-
130
- #Lpwd
131
- ✓ should return the help
132
- ✓ change to a folder
133
-
134
- #Ls
135
- ✓ should return the help
136
- ✓ should return all the datasets
137
- ✓ should list folders and files
138
- ✓ should list folders and files using wildcards
139
-
140
- #Mkdir
141
- ✓ should return the help
142
- ✓ should create a folder
143
- ✓ should create a nested folder
144
- ✓ should throw if trying to create a child of a file
145
- ✓ should throw if wrong parameters
146
-
147
- #Mv
148
- ✓ should return the help
149
- ✓ should rename a file (1010ms)
150
- ✓ should move a file to another folder
151
- ✓ should move many files to another folder
152
- ✓ should move a file to another subfolder
153
- ✓ should move and rename file to another folder
154
- ✓ should move file to another folder using wildcards
155
- ✓ should move file to another dataset using wildcards
156
- ✓ should move file managing duplicates
157
- ✓ should throw if parameters are missed or wrong
158
- ✓ should move files from and to other datasets (1014ms)
159
- ✓ should move the results of a find
160
-
161
- #Paste
162
- ✓ should return the help
163
- ✓ should paste the clipboard content to a new file (61ms)
164
- ✓ should paste the clipboard content to an existent file (86ms)
165
- ✓ should paste a single field to a yml card
166
-
167
- #Pwd
168
- ✓ should return the help
169
- ✓ should show the working folder
170
-
171
- #Quit
172
- ✓ should show the content of an external file via bash
173
-
174
- #Rm
175
- ✓ should return the help
176
- ✓ should delete a file with one version
177
- ✓ should delete many files usign wildcards
178
- ✓ should return errors if wrong parameters
179
- ✓ should delete some versions of a file (1009ms)
180
-
181
- #Shell
182
- ✓ should return the help
183
- ✓ should show the content of an external file via shell
184
-
185
- #Show
186
- ✓ should return the help
187
- ✓ should show the field password of a card
188
-
189
- #Tag
190
- ✓ should return the help
191
- ✓ should tag a file
192
- ✓ should remove a tag
193
- ✓ should list all the tags
194
- ✓ should show the file tagged as
195
- ✓ should show very long file tagged as
196
-
197
- #Totp
198
- ✓ should return the help
199
- ✓ should totp a file to the clipboard (394ms)
200
- ✓ should read a totp secret from an image and add the totp field to the card (44ms)
201
- ✓ should read a totp secret from an image and return the secret
202
- ✓ should throw if bad image
203
- ✓ should throw if missing parameters
204
- ✓ should throw if the yaml is malformed
205
- ✓ should read a totp secret from the clipboard (242ms)
206
-
207
- #Touch
208
- ✓ should return the help
209
- ✓ should create a file
210
- ✓ should create a file with content
211
- ✓ should duplicate a file
212
- ✓ should throw if trying to duplicate a non existing file
213
- ✓ should throw if trying to duplicate a folder
214
- ✓ should throw if trying to create a child of a file
215
- ✓ should throw if wrong parameters
216
- ✓ should create a file and generate a wallet
217
- New file "/folder2/file1" created.
218
- ✓ should generate 5 prefixed wallet (65ms)
219
- New file "/folder2/file1" created.
220
- ✓ should generate a wallet with mnemonic and 2 keys
221
-
222
- #Use
223
- ✓ should return the help
224
- ✓ should use a new dataset, creating it if does not exist
225
-
226
- #Ver
227
- ✓ should show the current version
228
-
229
- #Whoami
230
- ✓ should return the help
231
- ✓ should see who am I
232
-
233
-
234
- 155 passing (14s)
235
- 1 pending
236
- 1 failing
237
-
238
- 1) #Export
239
- should export a file to the current local folder:
240
-
241
- AssertionError: expected 'file.2' to equal 'file'
242
- + expected - actual
243
-
244
- -file.2
245
- +file
246
-
247
- at assertConsole (/Users/francescosullo/Projects/Secrez/secrez/packages/test-helpers/src/index.js:121:16)
248
- at Context.<anonymous> (test/commands/Export.test.js:94:5)
249
-
250
-
251
-
252
- --------------------|---------|----------|---------|---------|--------------------------------------
253
- File | % Stmts | % Branch | % Funcs | % Lines | Uncovered Line #s
254
- --------------------|---------|----------|---------|---------|--------------------------------------
255
- All files | 81.06 | 67.92 | 81.15 | 80.95 |
256
- src | 57.84 | 53.62 | 52.63 | 58.41 |
257
- Command.js | 79.66 | 78.72 | 76.92 | 81.03 | 32,55-62,73,80,119
258
- PreCommand.js | 8.82 | 0 | 0 | 8.82 | 6-97
259
- cliConfig.js | 100 | 100 | 100 | 100 |
260
- src/commands | 83.81 | 69.51 | 90.64 | 83.7 |
261
- Alias.js | 90.54 | 77.35 | 100 | 90.41 | 101,112,139,169,173,180,190
262
- Bash.js | 75 | 0 | 66.66 | 75 | 18-19
263
- Cat.js | 98.9 | 88.88 | 100 | 98.9 | 152
264
- Cd.js | 96.42 | 86.66 | 100 | 96.42 | 44
265
- Conf.js | 9.09 | 0 | 20 | 9.09 | 98-500
266
- Contacts.js | 87.17 | 74.32 | 100 | 87.06 | ...5-141,145,165,172,184,237,250,260
267
- Copy.js | 91.2 | 71.92 | 100 | 91.11 | 115,166,183,205-210,225-226,253
268
- Ds.js | 92.53 | 82.05 | 100 | 92.42 | 99,108-113,125
269
- Edit.js | 13.58 | 0 | 40 | 13.58 | 88-214
270
- Export.js | 90.17 | 76.92 | 100 | 90.17 | ...3-198,209,227-231,236,248,257,260
271
- Find.js | 93.58 | 86.66 | 100 | 93.42 | 101,164,200-203,209
272
- Help.js | 100 | 80 | 100 | 100 | 29
273
- Import.js | 93.2 | 85.48 | 100 | 93.13 | ...5,365,367,387,393,441,456-463,490
274
- Lcat.js | 100 | 85.71 | 100 | 100 | 54
275
- Lcd.js | 95.65 | 81.81 | 100 | 95.65 | 50
276
- Lls.js | 95.45 | 72.72 | 100 | 95.45 | 97
277
- Lpwd.js | 92.3 | 100 | 100 | 92.3 | 36
278
- Ls.js | 91.3 | 75 | 100 | 90.76 | 103,114-116,130,181
279
- Mkdir.js | 100 | 66.66 | 100 | 100 | 38-44
280
- Mv.js | 88.04 | 73.21 | 100 | 87.77 | 93-99,133,155,165-172
281
- Paste.js | 87.23 | 75 | 100 | 87.23 | 72,78,81,89,113,129
282
- Pwd.js | 92.3 | 100 | 100 | 92.3 | 33
283
- Quit.js | 90 | 50 | 100 | 90 | 27
284
- Rm.js | 94 | 80.95 | 100 | 93.87 | 63,126,134
285
- Shell.js | 88.23 | 60 | 100 | 88.23 | 38,55
286
- Show.js | 72 | 45.45 | 57.14 | 73.46 | ...8,100,106-114,117,123-126,132,143
287
- Ssh.js | 25 | 0 | 40 | 25 | 72-120
288
- Tag.js | 98.03 | 92.3 | 100 | 98.01 | 122,171
289
- Totp.js | 93.75 | 72.72 | 100 | 93.75 | 189-190,230,240,282-287
290
- Touch.js | 96 | 81.48 | 100 | 95.91 | 164,231
291
- Use.js | 96.77 | 89.47 | 100 | 96.77 | 68
292
- Ver.js | 90 | 66.66 | 100 | 90 | 25
293
- Whoami.js | 83.33 | 60 | 80 | 83.33 | 27,35,48
294
- index.js | 87.5 | 50 | 100 | 86.95 | 15,22,31
295
- src/prompts | 100 | 100 | 50 | 100 |
296
- MainPromptMock.js | 100 | 100 | 50 | 100 |
297
- src/utils | 68.82 | 62.5 | 56.25 | 68.44 |
298
- AliasManager.js | 100 | 91.66 | 100 | 100 | 47
299
- ContactManager.js | 73.33 | 60 | 85.71 | 73.33 | 12,34-36
300
- Fido2Client.js | 15.38 | 0 | 11.11 | 15.38 | 14-108
301
- HelpProto.js | 89.07 | 82.6 | 100 | 88.88 | 49,135-137,153-154,171-176,195
302
- Logger.js | 63.63 | 56.25 | 36.84 | 62.79 | ...25,37-49,57,65-69,74,84,88,93,105
303
- --------------------|---------|----------|---------|---------|--------------------------------------
54
+ ✓ should copy a file to the clipboard (406ms)
55
+ ✓ should copy a string to the clipboard (261ms)
304
56
   ELIFECYCLE  Test failed. See above for more details.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "secrez",
3
- "version": "2.1.7",
3
+ "version": "2.1.9",
4
4
  "license": "MIT",
5
5
  "nyc": {
6
6
  "include": "src",
@@ -10,7 +10,7 @@
10
10
  "@secrez/core": "~1.0.5",
11
11
  "@secrez/crypto": "~1.0.4",
12
12
  "@secrez/eth": "~0.0.4",
13
- "@secrez/fs": "~1.0.5",
13
+ "@secrez/fs": "~1.0.6",
14
14
  "@secrez/utils": "~1.0.4",
15
15
  "case": "^1.6.3",
16
16
  "chalk": "^3.0.0",
@@ -33,6 +33,7 @@
33
33
  "chai": "^4.5.0",
34
34
  "chalk": "^3.0.0",
35
35
  "cross-env": "^7.0.3",
36
+ "dotenv": "^17.2.2",
36
37
  "mocha": "^7.2.0",
37
38
  "nyc": "^15.1.0",
38
39
  "test-console": "^1.1.0"
package/src/Command.js CHANGED
@@ -84,6 +84,14 @@ class Command extends PreCommand {
84
84
  ][1] || undefined,
85
85
  ];
86
86
  }
87
+ // Handle < syntax for last path
88
+ if (
89
+ self.prompt.cache &&
90
+ self.prompt.cache.lastPath &&
91
+ options.path === "<"
92
+ ) {
93
+ return [options.path + self.prompt.cache.lastPath[0]];
94
+ }
87
95
  return await self.prompt[
88
96
  extraOptions.external ? "externalFs" : "internalFs"
89
97
  ].getFileList(options, true);
@@ -131,6 +139,41 @@ class Command extends PreCommand {
131
139
  }
132
140
  }
133
141
  }
142
+
143
+ /**
144
+ * Check for git conflicts before performing data-changing operations
145
+ * Returns true if the operation should proceed, false if it should be cancelled
146
+ */
147
+ async checkGitConflictsBeforeOperation() {
148
+ try {
149
+ const conflictCheck = await this.internalFs.checkGitSyncStatus();
150
+
151
+ if (conflictCheck.hasRisk) {
152
+ // Show the warning message
153
+ this.Logger.yellow(conflictCheck.message);
154
+
155
+ // Ask user if they want to continue
156
+ const shouldContinue = await this.useInput({
157
+ type: "confirm",
158
+ message: "Do you want to continue anyway?",
159
+ default: false,
160
+ });
161
+
162
+ if (!shouldContinue) {
163
+ this.Logger.grey("Operation cancelled.");
164
+ return false;
165
+ }
166
+ }
167
+
168
+ return true;
169
+ } catch (e) {
170
+ // If git check fails, log a warning but continue
171
+ this.Logger.yellow(
172
+ "Warning: Could not check git status. Proceeding anyway."
173
+ );
174
+ return true;
175
+ }
176
+ }
134
177
  }
135
178
 
136
179
  module.exports = Command;
package/src/Welcome.js CHANGED
@@ -3,7 +3,7 @@ const inquirer = require("inquirer");
3
3
  const fs = require("fs-extra");
4
4
  const Crypto = require("@secrez/crypto");
5
5
  const Logger = require("./utils/Logger");
6
- const Fido2Client = require("./utils/Fido2Client");
6
+ // const Fido2Client = require("./utils/Fido2Client"); // FIDO2 support removed
7
7
 
8
8
  class Welcome {
9
9
  async start(secrez, options) {
@@ -37,7 +37,7 @@ Thanks.`);
37
37
  if (await fs.pathExists(this.secrez.config.keysPath)) {
38
38
  let errorCode = await this.login();
39
39
  if (errorCode === 1) {
40
- await this.sharedLogin();
40
+ await this.handleDeprecatedFido2();
41
41
  }
42
42
  } else {
43
43
  Logger.grey("Please signup to create your local account");
@@ -111,6 +111,8 @@ Thanks.`);
111
111
  }
112
112
  }
113
113
 
114
+ // sharedLogin() method removed - FIDO2 support deprecated
115
+ /*
114
116
  async sharedLogin() {
115
117
  let fido2Client = new Fido2Client(this.secrez);
116
118
  let authenticator;
@@ -198,6 +200,7 @@ Thanks.`);
198
200
  }
199
201
  }
200
202
  }
203
+ */
201
204
 
202
205
  async signup() {
203
206
  for (;;) {
@@ -245,6 +248,44 @@ Thanks.`);
245
248
  }
246
249
  }
247
250
  }
251
+
252
+ async handleDeprecatedFido2() {
253
+ Logger.yellow("FIDO2 second factor authentication is no longer supported in this version.");
254
+ Logger.grey("Removing deprecated FIDO2 configuration...");
255
+
256
+ try {
257
+ const conf = await this.secrez.readConf();
258
+ const data = conf.data;
259
+
260
+ if (data.keys) {
261
+ // Remove all FIDO2 keys from the configuration
262
+ delete data.keys;
263
+
264
+ // Save the cleaned configuration
265
+ await this.secrez.saveConf(conf);
266
+
267
+ Logger.green("FIDO2 configuration has been removed successfully.");
268
+ Logger.grey("You can now login with your master password only.");
269
+
270
+ // Try to login again with the cleaned configuration
271
+ let errorCode = await this.login();
272
+ if (errorCode === 1) {
273
+ Logger.red("Login still failed. Please check your password or create a new account.");
274
+ // eslint-disable-next-line no-process-exit
275
+ process.exit(1);
276
+ }
277
+ } else {
278
+ Logger.red("No FIDO2 keys found, but login still requires second factor. This may indicate a corrupted configuration.");
279
+ // eslint-disable-next-line no-process-exit
280
+ process.exit(1);
281
+ }
282
+ } catch (e) {
283
+ Logger.red(`Failed to clean FIDO2 configuration: ${e.message}`);
284
+ Logger.grey("You may need to manually remove the keys.json file and create a new account.");
285
+ // eslint-disable-next-line no-process-exit
286
+ process.exit(1);
287
+ }
288
+ }
248
289
  }
249
290
 
250
291
  module.exports = new Welcome();
@@ -200,6 +200,21 @@ class Alias extends require("../Command") {
200
200
  }
201
201
  try {
202
202
  this.validate(options);
203
+
204
+ // Check for git conflicts before creating/modifying/deleting aliases
205
+ if (
206
+ options.commandLine ||
207
+ options.previousCommand ||
208
+ options.rename ||
209
+ options.delete
210
+ ) {
211
+ const shouldProceed = await this.checkGitConflictsBeforeOperation();
212
+ if (!shouldProceed) {
213
+ await this.prompt.run();
214
+ return;
215
+ }
216
+ }
217
+
203
218
  let result = await this.alias(options);
204
219
  if (!Array.isArray(result)) {
205
220
  result = [result];
@@ -187,6 +187,8 @@ class Cat extends require("../Command") {
187
187
  this.validate(options, {
188
188
  path: true,
189
189
  });
190
+ // Track the last path used
191
+ this.prompt.setLastPath(options.path);
190
192
  let fn = path.basename(options.path);
191
193
  let data = await this.cat(options);
192
194
  let extra = options.all || options.metadata || options.versions;
@@ -486,6 +486,15 @@ class Conf extends require("../Command") {
486
486
  // options.list = true
487
487
  // }
488
488
  this.validate(options);
489
+
490
+ // Check for git conflicts before changing password or iterations
491
+ if (options.newPassword || options.newIterationsNumber) {
492
+ const shouldProceed = await this.checkGitConflictsBeforeOperation();
493
+ if (!shouldProceed) {
494
+ return;
495
+ }
496
+ }
497
+
489
498
  // if (options.fido2 && options.recoveryCode) {
490
499
  // throw new Error('Conflicting params. Launch "conf -h" for examples.')
491
500
  // }
@@ -260,6 +260,16 @@ class Contacts extends require("../Command") {
260
260
  options.list = true;
261
261
  }
262
262
  this.validate(options);
263
+
264
+ // Check for git conflicts before adding/updating/deleting contacts
265
+ if (options.add || options.update || options.delete || options.rename) {
266
+ const shouldProceed = await this.checkGitConflictsBeforeOperation();
267
+ if (!shouldProceed) {
268
+ await this.prompt.run();
269
+ return;
270
+ }
271
+ }
272
+
263
273
  let result = await this.contacts(options);
264
274
  if (!Array.isArray(result)) {
265
275
  result = [result];
@@ -139,6 +139,16 @@ class Ds extends require("../Command") {
139
139
  options.list = true;
140
140
  }
141
141
  this.validate(options);
142
+
143
+ // Check for git conflicts before creating/renaming/deleting datasets
144
+ if (options.create || options.rename || options.delete) {
145
+ const shouldProceed = await this.checkGitConflictsBeforeOperation();
146
+ if (!shouldProceed) {
147
+ await this.prompt.run();
148
+ return;
149
+ }
150
+ }
151
+
142
152
  let result = await this.ds(options);
143
153
  if (result) {
144
154
  if (options.list) {
@@ -184,6 +184,14 @@ class Edit extends require("../Command") {
184
184
  this.validate(options, {
185
185
  path: true,
186
186
  });
187
+
188
+ if (!options.help) {
189
+ // Check for git conflicts before editing files (edit always changes something)
190
+ const shouldProceed = await this.checkGitConflictsBeforeOperation();
191
+ if (!shouldProceed) {
192
+ return;
193
+ }
194
+ }
187
195
  currentEditor = process.env.EDITOR;
188
196
  if (options.internal) {
189
197
  process.env.EDITOR = this.getTinyCliEditorBinPath();
@@ -0,0 +1,67 @@
1
+ const chalk = require("chalk");
2
+ const { yamlStringify } = require("@secrez/utils");
3
+
4
+ class Git extends require("../Command") {
5
+ setHelpAndCompletion() {
6
+ this.cliConfig.completion.git = {
7
+ _func: this.selfCompletion(this),
8
+ _self: this,
9
+ };
10
+ this.cliConfig.completion.help.git = true;
11
+ this.optionDefinitions = [
12
+ {
13
+ name: "help",
14
+ alias: "h",
15
+ type: Boolean,
16
+ },
17
+ {
18
+ name: "status",
19
+ alias: "s",
20
+ type: Boolean,
21
+ },
22
+ ];
23
+ }
24
+
25
+ help() {
26
+ return {
27
+ description: ["Check a git repository status."],
28
+ examples: [["git -s", "Check the git repository status"]],
29
+ };
30
+ }
31
+
32
+ async git(options = {}) {
33
+ const isGit = await this.internalFs.gitConflictChecker.isGitRepository();
34
+ if (isGit) {
35
+ if (options.status) {
36
+ let status = await this.internalFs.gitConflictChecker.getGitStatus();
37
+ let warning =
38
+ await this.internalFs.gitConflictChecker.getWarningMessage(status);
39
+ if (warning) {
40
+ return chalk.yellow(warning);
41
+ } else return "No remote changes found.";
42
+ }
43
+ } else {
44
+ return "Not a git repository";
45
+ }
46
+ }
47
+
48
+ async exec(options = {}) {
49
+ if (options.help) {
50
+ return this.showHelp();
51
+ }
52
+ try {
53
+ // if the user didn't pass any option, we default to options.status
54
+ if (!Object.keys(options).length) {
55
+ options.status = true;
56
+ }
57
+ this.validate(options);
58
+ let result = await this.git(options);
59
+ this.Logger.reset(result);
60
+ } catch (e) {
61
+ this.Logger.red(e.message);
62
+ }
63
+ await this.prompt.run();
64
+ }
65
+ }
66
+
67
+ module.exports = Git;
@@ -449,6 +449,16 @@ class Import extends require("../Command") {
449
449
  }
450
450
  try {
451
451
  this.validate(options);
452
+
453
+ // Check for git conflicts before importing files (skip if help or simulate)
454
+ if (!options.help && !options.simulate) {
455
+ const shouldProceed = await this.checkGitConflictsBeforeOperation();
456
+ if (!shouldProceed) {
457
+ await this.prompt.run();
458
+ return;
459
+ }
460
+ }
461
+
452
462
  if (options.expand) {
453
463
  await this.expand(options);
454
464
  } else {
@@ -163,6 +163,10 @@ class Ls extends require("../Command") {
163
163
  }
164
164
  try {
165
165
  this.validate(options);
166
+ // Track the last path used if a path was specified
167
+ if (options.path) {
168
+ this.prompt.setLastPath(options.path);
169
+ }
166
170
  let list = await this.ls(options);
167
171
  list = list.filter((e) => !/^\./.test(e) || options.all).sort();
168
172
  if (list.length) {
@@ -48,6 +48,16 @@ class Mkdir extends require("../Command") {
48
48
  try {
49
49
  this.validate(options);
50
50
  this.checkPath(options);
51
+
52
+ // Check for git conflicts before creating directories
53
+ if (!options.help) {
54
+ const shouldProceed = await this.checkGitConflictsBeforeOperation();
55
+ if (!shouldProceed) {
56
+ await this.prompt.run();
57
+ return;
58
+ }
59
+ }
60
+
51
61
  let data = await this.internalFs.getTreeIndexAndPath(options.path);
52
62
  let sanitizedPath = Entry.sanitizePath(data.path);
53
63
  if (sanitizedPath !== data.path) {
@@ -147,6 +147,16 @@ class Mv extends require("../Command") {
147
147
  }
148
148
  try {
149
149
  this.validate(options);
150
+
151
+ // Check for git conflicts before moving/renaming files
152
+ if (!options.help) {
153
+ const shouldProceed = await this.checkGitConflictsBeforeOperation();
154
+ if (!shouldProceed) {
155
+ await this.prompt.run();
156
+ return;
157
+ }
158
+ }
159
+
150
160
  if (options.find) {
151
161
  options.newPath = options.destination;
152
162
  options.path = options.find;
@@ -122,6 +122,16 @@ class Paste extends require("../Command") {
122
122
  }
123
123
  try {
124
124
  this.validate(options);
125
+
126
+ // Check for git conflicts before pasting content
127
+ if (!options.help) {
128
+ const shouldProceed = await this.checkGitConflictsBeforeOperation();
129
+ if (!shouldProceed) {
130
+ await this.prompt.run();
131
+ return;
132
+ }
133
+ }
134
+
125
135
  let name = await this.paste(options);
126
136
  this.Logger.grey("Pasted the clipboard to:");
127
137
  this.Logger.reset(name);
@@ -117,6 +117,16 @@ class Rm extends require("../Command") {
117
117
  } else {
118
118
  try {
119
119
  this.validate(options);
120
+
121
+ // Check for git conflicts before removing files
122
+ if (!options.help) {
123
+ const shouldProceed = await this.checkGitConflictsBeforeOperation();
124
+ if (!shouldProceed) {
125
+ await this.prompt.run();
126
+ return;
127
+ }
128
+ }
129
+
120
130
  let deleted = await this.rm(options);
121
131
  if (deleted.length === 0) {
122
132
  this.Logger.grey("No files have been deleted.");
@@ -135,6 +135,8 @@ class Show extends require("../Command") {
135
135
  this.validate(options, {
136
136
  path: true,
137
137
  });
138
+ // Track the last path used
139
+ this.prompt.setLastPath(options.path);
138
140
  const content = await this.show(options);
139
141
  if (content) {
140
142
  this.Logger.reset(content);
@@ -196,6 +196,16 @@ class Tag extends require("../Command") {
196
196
  }
197
197
  try {
198
198
  this.validate(options);
199
+
200
+ // Check for git conflicts before adding/removing tags
201
+ if (options.add || options.remove) {
202
+ const shouldProceed = await this.checkGitConflictsBeforeOperation();
203
+ if (!shouldProceed) {
204
+ await this.prompt.run();
205
+ return;
206
+ }
207
+ }
208
+
199
209
  let result = await this.tag(options);
200
210
  if (options.list) {
201
211
  if (options.global) {
@@ -293,6 +293,21 @@ class Totp extends require("../Command") {
293
293
  }
294
294
  try {
295
295
  this.validate(options);
296
+
297
+ // Check for git conflicts before setting TOTP secrets
298
+ if (options.set || options.fromClipboard || options.fromImage) {
299
+ const shouldProceed = await this.checkGitConflictsBeforeOperation();
300
+ if (!shouldProceed) {
301
+ await this.prompt.run();
302
+ return;
303
+ }
304
+ }
305
+
306
+ // Track the last path used if a path was specified
307
+ if (options.path) {
308
+ this.prompt.setLastPath(options.path);
309
+ }
310
+
296
311
  let token = await this.totp(options);
297
312
  if (options.fromImage || options.fromClipboard) {
298
313
  this.Logger.grey(token);
@@ -179,6 +179,15 @@ class Touch extends require("../Command") {
179
179
  try {
180
180
  this.validate(options);
181
181
  this.checkPath(options);
182
+
183
+ // Check for git conflicts before creating/modifying files
184
+ if (!options.help) {
185
+ const shouldProceed = await this.checkGitConflictsBeforeOperation();
186
+ if (!shouldProceed) {
187
+ await this.prompt.run();
188
+ return;
189
+ }
190
+ }
182
191
  /* istanbul ignore if */
183
192
  if (!options.generateWallet) {
184
193
  if (options.notVisibleContent) {
@@ -75,6 +75,16 @@ class Use extends require("../Command") {
75
75
  }
76
76
  try {
77
77
  this.validate(options);
78
+
79
+ // Check for git conflicts before creating new datasets
80
+ if (options.create) {
81
+ const shouldProceed = await this.checkGitConflictsBeforeOperation();
82
+ if (!shouldProceed) {
83
+ await this.prompt.run();
84
+ return;
85
+ }
86
+ }
87
+
78
88
  let result = await this.use(options);
79
89
  if (result) {
80
90
  this.Logger.reset(result);
@@ -243,6 +243,10 @@ class CommandPrompt {
243
243
  if (/ (#|£)\d+(\w+:|)\/[\w/]+/.test(line)) {
244
244
  line = line.replace(/ (#|£)\d+((\w+:|)\/[\w/]+)/, " $2");
245
245
  }
246
+ // Handle < syntax for last path
247
+ if (/ </.test(line)) {
248
+ line = line.replace(/</, "");
249
+ }
246
250
  return line;
247
251
  }
248
252
 
@@ -75,6 +75,14 @@ class MainPrompt extends require("./CommandPrompt") {
75
75
  }
76
76
  }
77
77
 
78
+ setLastPath(path) {
79
+ this.setCache("lastPath", 0, path);
80
+ }
81
+
82
+ getLastPath() {
83
+ return this.getCache("lastPath", 0);
84
+ }
85
+
78
86
  prePromptMessage(options = {}) {
79
87
  this.resetTimeout();
80
88
  return chalk.reset(
@@ -18,9 +18,31 @@ class MainPromptMock {
18
18
  this.cache = {};
19
19
  }
20
20
 
21
- setCache() {}
21
+ setCache(name, index, content) {
22
+ if (!this.cache[name]) {
23
+ this.cache[name] = {};
24
+ }
25
+ this.cache[name][index] = content;
26
+ }
27
+
28
+ getCache(name, index) {
29
+ if (!this.cache[name]) {
30
+ return null;
31
+ }
32
+ if (typeof index !== "undefined") {
33
+ return this.cache[name][index];
34
+ } else {
35
+ return this.cache[name];
36
+ }
37
+ }
22
38
 
23
- getCache() {}
39
+ setLastPath(path) {
40
+ this.setCache("lastPath", 0, path);
41
+ }
42
+
43
+ getLastPath() {
44
+ return this.getCache("lastPath", 0);
45
+ }
24
46
 
25
47
  async run(options) {}
26
48