sealcode 1.1.0 → 1.1.1
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/package.json +1 -1
- package/src/cli-grants.js +33 -9
- package/src/cli.js +1 -0
package/package.json
CHANGED
package/src/cli-grants.js
CHANGED
|
@@ -74,17 +74,38 @@ function getActiveConfig(projectRoot) {
|
|
|
74
74
|
* a real cryptographic bug; we don't want to silently downgrade in that
|
|
75
75
|
* case).
|
|
76
76
|
*/
|
|
77
|
-
async function maybeWrapKeyForRecipient({
|
|
77
|
+
async function maybeWrapKeyForRecipient({
|
|
78
|
+
projectRoot,
|
|
79
|
+
recipientEmail,
|
|
80
|
+
verbose = false,
|
|
81
|
+
resolveKey = null,
|
|
82
|
+
}) {
|
|
78
83
|
if (!recipientEmail) return null;
|
|
79
84
|
|
|
80
|
-
// Need the master key K to wrap.
|
|
81
|
-
//
|
|
85
|
+
// Need the master key K to wrap. Prefer a cached session; if none, ask
|
|
86
|
+
// the caller (cli.js) to prompt for the passphrase. We deliberately do
|
|
87
|
+
// NOT silently downgrade to "passphrase fallback" here — the whole point
|
|
88
|
+
// of `--email` is to spare the recipient the passphrase exchange.
|
|
82
89
|
const config = getActiveConfig(projectRoot);
|
|
83
90
|
if (!isInitialized(projectRoot, config.lockedDir)) return null;
|
|
84
|
-
|
|
91
|
+
let K = loadSession(projectRoot);
|
|
92
|
+
if (!K && typeof resolveKey === 'function') {
|
|
93
|
+
if (verbose) {
|
|
94
|
+
ui.step('No cached master key — prompting for passphrase so we can wrap for the recipient.');
|
|
95
|
+
}
|
|
96
|
+
try {
|
|
97
|
+
K = await resolveKey(projectRoot, config);
|
|
98
|
+
} catch (err) {
|
|
99
|
+
if (verbose) {
|
|
100
|
+
ui.warn(`Could not derive master key (${err.message || err}). Will mint without wrapping.`);
|
|
101
|
+
}
|
|
102
|
+
return null;
|
|
103
|
+
}
|
|
104
|
+
}
|
|
85
105
|
if (!K) {
|
|
86
106
|
if (verbose) {
|
|
87
|
-
ui.
|
|
107
|
+
ui.warn('No cached master key — minting code WITHOUT wrapped key. Recipient will need the passphrase.');
|
|
108
|
+
ui.hint('Run `sealcode unlock` first, or supply a passphrase prompt, to enable passphrase-free sharing.');
|
|
88
109
|
}
|
|
89
110
|
return null;
|
|
90
111
|
}
|
|
@@ -100,13 +121,14 @@ async function maybeWrapKeyForRecipient({ projectRoot, recipientEmail, verbose =
|
|
|
100
121
|
} catch (err) {
|
|
101
122
|
if (err instanceof ApiError) {
|
|
102
123
|
if (err.status === 404) {
|
|
103
|
-
// Either the user doesn't exist or hasn't published a pubkey
|
|
104
|
-
// yet. We still mint the code; the recipient just falls back to
|
|
105
|
-
// the legacy flow when they redeem.
|
|
106
124
|
if (verbose) {
|
|
125
|
+
ui.warn(
|
|
126
|
+
`Recipient ${recipientEmail} hasn't signed in to sealcode.dev yet, so no pubkey is on file.`,
|
|
127
|
+
);
|
|
107
128
|
ui.hint(
|
|
108
|
-
|
|
129
|
+
'Ask them to visit https://sealcode.dev/login, then re-run `sealcode share --email`.',
|
|
109
130
|
);
|
|
131
|
+
ui.hint('Continuing with passphrase-fallback for this code…');
|
|
110
132
|
}
|
|
111
133
|
return null;
|
|
112
134
|
}
|
|
@@ -146,6 +168,7 @@ async function runShare({
|
|
|
146
168
|
singleDeviceEnforce = false,
|
|
147
169
|
ndaText = null,
|
|
148
170
|
json = false,
|
|
171
|
+
resolveKey = null,
|
|
149
172
|
}) {
|
|
150
173
|
const link = requireLink(projectRoot);
|
|
151
174
|
|
|
@@ -159,6 +182,7 @@ async function runShare({
|
|
|
159
182
|
projectRoot,
|
|
160
183
|
recipientEmail: email,
|
|
161
184
|
verbose: !json,
|
|
185
|
+
resolveKey,
|
|
162
186
|
});
|
|
163
187
|
} catch (err) {
|
|
164
188
|
// Network errors during pubkey lookup shouldn't be silent — degrade
|