shogun-button-react 6.8.3 → 6.9.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/README.md +769 -769
- package/dist/components/ShogunButton.d.ts +2 -2
- package/dist/components/ShogunButton.js +124 -4
- package/dist/connector.js +2 -1
- package/dist/index.js +1 -1
- package/dist/interfaces/connector-options.d.ts +5 -0
- package/package.json +2 -2
|
@@ -34,14 +34,14 @@ type ShogunButtonProviderProps = {
|
|
|
34
34
|
userPub: string;
|
|
35
35
|
username: string;
|
|
36
36
|
password?: string;
|
|
37
|
-
authMethod?: "password" | "web3" | "webauthn" | "nostr" | "zkproof";
|
|
37
|
+
authMethod?: "password" | "web3" | "webauthn" | "nostr" | "zkproof" | "challenge" | "seed" | "pair";
|
|
38
38
|
}) => void;
|
|
39
39
|
onSignupSuccess?: (data: {
|
|
40
40
|
userPub: string;
|
|
41
41
|
username: string;
|
|
42
42
|
password?: string;
|
|
43
43
|
seedPhrase?: string;
|
|
44
|
-
authMethod?: "password" | "web3" | "webauthn" | "nostr" | "zkproof";
|
|
44
|
+
authMethod?: "password" | "web3" | "webauthn" | "nostr" | "zkproof" | "challenge" | "seed" | "pair";
|
|
45
45
|
}) => void;
|
|
46
46
|
onError?: (error: string) => void;
|
|
47
47
|
};
|
|
@@ -192,6 +192,35 @@ export function ShogunButtonProvider({ children, core, options, onLoginSuccess,
|
|
|
192
192
|
throw new Error("ZK-Proof requires ShogunCore");
|
|
193
193
|
}
|
|
194
194
|
break;
|
|
195
|
+
case "challenge":
|
|
196
|
+
username = args[0];
|
|
197
|
+
if (!username)
|
|
198
|
+
throw new Error("Username required for challenge login");
|
|
199
|
+
if (isShogunCore(core)) {
|
|
200
|
+
const challengePlugin = core.getPlugin("challenge");
|
|
201
|
+
if (!challengePlugin)
|
|
202
|
+
throw new Error("Challenge plugin not available");
|
|
203
|
+
result = await challengePlugin.login(username);
|
|
204
|
+
authMethod = "challenge";
|
|
205
|
+
}
|
|
206
|
+
else {
|
|
207
|
+
throw new Error("Challenge auth requires ShogunCore");
|
|
208
|
+
}
|
|
209
|
+
break;
|
|
210
|
+
case "seed":
|
|
211
|
+
username = args[0];
|
|
212
|
+
const mnemonic = args[1];
|
|
213
|
+
if (!username || !mnemonic) {
|
|
214
|
+
throw new Error("Username and seed phrase are required");
|
|
215
|
+
}
|
|
216
|
+
if (isShogunCore(core)) {
|
|
217
|
+
result = await core.loginWithSeed(username, mnemonic);
|
|
218
|
+
authMethod = "seed";
|
|
219
|
+
}
|
|
220
|
+
else {
|
|
221
|
+
throw new Error("Seed authentication requires ShogunCore");
|
|
222
|
+
}
|
|
223
|
+
break;
|
|
195
224
|
default:
|
|
196
225
|
throw new Error("Unsupported login method");
|
|
197
226
|
}
|
|
@@ -615,6 +644,8 @@ const ZkProofIcon = () => (React.createElement("svg", { xmlns: "http://www.w3.or
|
|
|
615
644
|
React.createElement("path", { d: "M12 2L2 7l10 5 10-5-10-5z" }),
|
|
616
645
|
React.createElement("path", { d: "M2 17l10 5 10-5" }),
|
|
617
646
|
React.createElement("path", { d: "M2 12l10 5 10-5" })));
|
|
647
|
+
const ChallengeIcon = () => (React.createElement("svg", { xmlns: "http://www.w3.org/2000/svg", width: "20", height: "20", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2", strokeLinecap: "round", strokeLinejoin: "round" },
|
|
648
|
+
React.createElement("polygon", { points: "12 2 15.09 8.26 22 9.27 17 14.14 18.18 21.02 12 17.77 5.82 21.02 7 14.14 2 9.27 8.91 8.26 12 2" })));
|
|
618
649
|
const ExportIcon = () => (React.createElement("svg", { xmlns: "http://www.w3.org/2000/svg", width: "20", height: "20", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2", strokeLinecap: "round", strokeLinejoin: "round" },
|
|
619
650
|
React.createElement("path", { d: "M14 2H6a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V8z" }),
|
|
620
651
|
React.createElement("polyline", { points: "14,2 14,8 20,8" }),
|
|
@@ -649,6 +680,7 @@ export const ShogunButton = (() => {
|
|
|
649
680
|
const [showZkTrapdoorCopySuccess, setShowZkTrapdoorCopySuccess] = useState(false);
|
|
650
681
|
const [webauthnSeedPhrase, setWebauthnSeedPhrase] = useState("");
|
|
651
682
|
const [webauthnRecoverySeed, setWebauthnRecoverySeed] = useState("");
|
|
683
|
+
const [formMnemonic, setFormMnemonic] = useState("");
|
|
652
684
|
const dropdownRef = useRef(null);
|
|
653
685
|
// Handle click outside to close dropdown
|
|
654
686
|
useEffect(() => {
|
|
@@ -891,6 +923,50 @@ export const ShogunButton = (() => {
|
|
|
891
923
|
setLoading(false);
|
|
892
924
|
}
|
|
893
925
|
};
|
|
926
|
+
const handleChallengeAuth = () => {
|
|
927
|
+
if (!hasPlugin("challenge")) {
|
|
928
|
+
setError("Challenge plugin not available");
|
|
929
|
+
return;
|
|
930
|
+
}
|
|
931
|
+
setAuthView("challenge-username");
|
|
932
|
+
};
|
|
933
|
+
const handleChallengeLogin = async () => {
|
|
934
|
+
setError("");
|
|
935
|
+
setLoading(true);
|
|
936
|
+
try {
|
|
937
|
+
if (!formUsername.trim()) {
|
|
938
|
+
throw new Error("Please enter your username");
|
|
939
|
+
}
|
|
940
|
+
await handleAuth("challenge", formUsername);
|
|
941
|
+
setModalIsOpen(false);
|
|
942
|
+
}
|
|
943
|
+
catch (e) {
|
|
944
|
+
setError(e.message || "Challenge login failed");
|
|
945
|
+
}
|
|
946
|
+
finally {
|
|
947
|
+
setLoading(false);
|
|
948
|
+
}
|
|
949
|
+
};
|
|
950
|
+
const handleSeedLogin = async () => {
|
|
951
|
+
setError("");
|
|
952
|
+
setLoading(true);
|
|
953
|
+
try {
|
|
954
|
+
if (!formUsername.trim()) {
|
|
955
|
+
throw new Error("Please enter your username");
|
|
956
|
+
}
|
|
957
|
+
if (!formMnemonic.trim()) {
|
|
958
|
+
throw new Error("Please enter your seed phrase");
|
|
959
|
+
}
|
|
960
|
+
await handleAuth("seed", formUsername.trim(), formMnemonic.trim());
|
|
961
|
+
setModalIsOpen(false);
|
|
962
|
+
}
|
|
963
|
+
catch (e) {
|
|
964
|
+
setError(e.message || "Seed login failed");
|
|
965
|
+
}
|
|
966
|
+
finally {
|
|
967
|
+
setLoading(false);
|
|
968
|
+
}
|
|
969
|
+
};
|
|
894
970
|
const handleRecover = async () => {
|
|
895
971
|
setError("");
|
|
896
972
|
setLoading(true);
|
|
@@ -1005,6 +1081,7 @@ export const ShogunButton = (() => {
|
|
|
1005
1081
|
setShowZkTrapdoorCopySuccess(false);
|
|
1006
1082
|
setWebauthnSeedPhrase("");
|
|
1007
1083
|
setWebauthnRecoverySeed("");
|
|
1084
|
+
setFormMnemonic("");
|
|
1008
1085
|
};
|
|
1009
1086
|
const openModal = () => {
|
|
1010
1087
|
resetForm();
|
|
@@ -1045,6 +1122,12 @@ export const ShogunButton = (() => {
|
|
|
1045
1122
|
React.createElement("button", { type: "button", className: "shogun-auth-option-button", onClick: () => handleAuth("nostr"), disabled: loading },
|
|
1046
1123
|
React.createElement(NostrIcon, null),
|
|
1047
1124
|
formMode === "login" ? "Login with Nostr" : "Signup with Nostr"))),
|
|
1125
|
+
options.showChallenge !== false && hasPlugin("challenge") && (React.createElement("div", { className: "shogun-auth-option-group" },
|
|
1126
|
+
React.createElement("button", { type: "button", className: "shogun-auth-option-button", onClick: handleChallengeAuth, disabled: loading },
|
|
1127
|
+
React.createElement(ChallengeIcon, null),
|
|
1128
|
+
formMode === "login"
|
|
1129
|
+
? "Login with Challenge"
|
|
1130
|
+
: "Signup with Challenge (N/A)"))),
|
|
1048
1131
|
options.showZkProof !== false && hasPlugin("zkproof") && (React.createElement("div", { className: "shogun-auth-option-group" },
|
|
1049
1132
|
React.createElement("button", { type: "button", className: "shogun-auth-option-button", onClick: handleZkProofAuth, disabled: loading },
|
|
1050
1133
|
React.createElement(ZkProofIcon, null),
|
|
@@ -1058,6 +1141,9 @@ export const ShogunButton = (() => {
|
|
|
1058
1141
|
formMode === "login"
|
|
1059
1142
|
? "Login with Password"
|
|
1060
1143
|
: "Signup with Password"),
|
|
1144
|
+
options.showSeedLogin !== false && formMode === "login" && (React.createElement("button", { type: "button", className: "shogun-auth-option-button", onClick: () => setAuthView("seed-login"), disabled: loading },
|
|
1145
|
+
React.createElement(KeyIcon, null),
|
|
1146
|
+
"Login with Seed phrase")),
|
|
1061
1147
|
formMode === "login" && (React.createElement("button", { type: "button", className: "shogun-auth-option-button", onClick: () => setAuthView("import"), disabled: loading },
|
|
1062
1148
|
React.createElement(ImportIcon, null),
|
|
1063
1149
|
"Import Gun Pair"))));
|
|
@@ -1385,6 +1471,35 @@ export const ShogunButton = (() => {
|
|
|
1385
1471
|
textAlign: "center",
|
|
1386
1472
|
} }, "\u2705 You're now logged in with WebAuthn!"),
|
|
1387
1473
|
React.createElement("button", { type: "button", className: "shogun-submit-button", style: { marginTop: "16px" }, onClick: finalizeZkProofSignup }, "Close and Start Using App")));
|
|
1474
|
+
const renderChallengeForm = () => (React.createElement("div", { className: "shogun-auth-form" },
|
|
1475
|
+
React.createElement("div", { className: "shogun-form-group" },
|
|
1476
|
+
React.createElement("label", { htmlFor: "challenge-username" },
|
|
1477
|
+
React.createElement(UserIcon, null),
|
|
1478
|
+
React.createElement("span", null, "Username")),
|
|
1479
|
+
React.createElement("input", { type: "text", id: "challenge-username", value: formUsername, onChange: (e) => setFormUsername(e.target.value), disabled: loading, required: true, placeholder: "Enter your username", autoFocus: true })),
|
|
1480
|
+
React.createElement("button", { type: "button", className: "shogun-submit-button", onClick: handleChallengeLogin, disabled: loading }, loading ? "Processing..." : "Continue"),
|
|
1481
|
+
React.createElement("button", { type: "button", className: "shogun-back-button", onClick: () => setAuthView("options"), disabled: loading }, "Back")));
|
|
1482
|
+
const renderSeedLoginForm = () => (React.createElement("div", { className: "shogun-auth-form" },
|
|
1483
|
+
React.createElement("h3", null, "Login with Seed Phrase"),
|
|
1484
|
+
React.createElement("div", { className: "shogun-form-group" },
|
|
1485
|
+
React.createElement("label", { htmlFor: "seed-username" },
|
|
1486
|
+
React.createElement(UserIcon, null),
|
|
1487
|
+
React.createElement("span", null, "Username")),
|
|
1488
|
+
React.createElement("input", { type: "text", id: "seed-username", value: formUsername, onChange: (e) => setFormUsername(e.target.value), disabled: loading, required: true, placeholder: "Enter your username", autoFocus: true })),
|
|
1489
|
+
React.createElement("div", { className: "shogun-form-group" },
|
|
1490
|
+
React.createElement("label", { htmlFor: "seed-mnemonic" },
|
|
1491
|
+
React.createElement(KeyIcon, null),
|
|
1492
|
+
React.createElement("span", null, "Seed Phrase (12/24 words)")),
|
|
1493
|
+
React.createElement("textarea", { id: "seed-mnemonic", value: formMnemonic, onChange: (e) => setFormMnemonic(e.target.value), disabled: loading, required: true, placeholder: "Enter your seed phrase...", rows: 3, style: {
|
|
1494
|
+
fontFamily: "monospace",
|
|
1495
|
+
fontSize: "12px",
|
|
1496
|
+
width: "100%",
|
|
1497
|
+
padding: "8px",
|
|
1498
|
+
border: "1px solid #ccc",
|
|
1499
|
+
borderRadius: "4px",
|
|
1500
|
+
} })),
|
|
1501
|
+
React.createElement("button", { type: "button", className: "shogun-submit-button", onClick: handleSeedLogin, disabled: loading || !formUsername.trim() || !formMnemonic.trim() }, loading ? "Processing..." : "Login with Seed"),
|
|
1502
|
+
React.createElement("button", { type: "button", className: "shogun-back-button", onClick: () => setAuthView("options"), disabled: loading }, "Back")));
|
|
1388
1503
|
const renderImportForm = () => (React.createElement("div", { className: "shogun-auth-form" },
|
|
1389
1504
|
React.createElement("h3", null, "Import Gun Pair"),
|
|
1390
1505
|
React.createElement("div", { style: {
|
|
@@ -1459,9 +1574,11 @@ export const ShogunButton = (() => {
|
|
|
1459
1574
|
? "WebAuthn"
|
|
1460
1575
|
: authView === "zkproof-login"
|
|
1461
1576
|
? "ZK-Proof Login"
|
|
1462
|
-
:
|
|
1463
|
-
? "Login"
|
|
1464
|
-
:
|
|
1577
|
+
: authView === "seed-login"
|
|
1578
|
+
? "Login with Seed"
|
|
1579
|
+
: formMode === "login"
|
|
1580
|
+
? "Login"
|
|
1581
|
+
: "Sign Up"),
|
|
1465
1582
|
React.createElement("button", { className: "shogun-close-button", onClick: closeModal, "aria-label": "Close" },
|
|
1466
1583
|
React.createElement(CloseIcon, null))),
|
|
1467
1584
|
React.createElement("div", { className: "shogun-modal-content" },
|
|
@@ -1472,6 +1589,7 @@ export const ShogunButton = (() => {
|
|
|
1472
1589
|
React.createElement("button", { type: "button", className: "shogun-toggle-mode shogun-prominent-toggle", onClick: toggleMode, disabled: loading }, formMode === "login"
|
|
1473
1590
|
? "Don't have an account? Sign up"
|
|
1474
1591
|
: "Already have an account? Log in")))),
|
|
1592
|
+
authView === "seed-login" && renderSeedLoginForm(),
|
|
1475
1593
|
authView === "password" && (React.createElement(React.Fragment, null,
|
|
1476
1594
|
React.createElement("button", { className: "shogun-back-button", onClick: () => setAuthView("options") }, "\u2190 Back"),
|
|
1477
1595
|
renderPasswordForm())),
|
|
@@ -1487,7 +1605,9 @@ export const ShogunButton = (() => {
|
|
|
1487
1605
|
renderWebauthnSignupResult(),
|
|
1488
1606
|
authView === "zkproof-login" && renderZkProofLoginForm(),
|
|
1489
1607
|
authView === "zkproof-signup-result" &&
|
|
1490
|
-
renderZkProofSignupResult()
|
|
1608
|
+
renderZkProofSignupResult(),
|
|
1609
|
+
authView === "challenge-username" &&
|
|
1610
|
+
renderChallengeForm()))))));
|
|
1491
1611
|
};
|
|
1492
1612
|
Button.displayName = "ShogunButton";
|
|
1493
1613
|
return Object.assign(Button, {
|
package/dist/connector.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { ShogunCore } from "shogun-core";
|
|
2
2
|
export async function shogunConnector(options) {
|
|
3
|
-
const { gunInstance, appName, timeouts, webauthn, nostr, web3, zkproof, showWebauthn, showNostr, showMetamask, showZkProof, darkMode, enableGunDebug = true, enableConnectionMonitoring = true, defaultPageSize = 20, connectionTimeout = 10000, debounceInterval = 100, crypto, ...restOptions } = options;
|
|
3
|
+
const { gunInstance, appName, timeouts, webauthn, nostr, web3, zkproof, challenge, showWebauthn, showNostr, showMetamask, showZkProof, showChallenge, darkMode, enableGunDebug = true, enableConnectionMonitoring = true, defaultPageSize = 20, connectionTimeout = 10000, debounceInterval = 100, crypto, ...restOptions } = options;
|
|
4
4
|
let core = null;
|
|
5
5
|
let gun = null;
|
|
6
6
|
gun = gunInstance;
|
|
@@ -18,6 +18,7 @@ export async function shogunConnector(options) {
|
|
|
18
18
|
enabled: true,
|
|
19
19
|
defaultGroupId: zkproof.defaultGroupId || "shogun-users",
|
|
20
20
|
} : undefined,
|
|
21
|
+
challenge: (challenge === null || challenge === void 0 ? void 0 : challenge.enabled) ? { enabled: true } : undefined,
|
|
21
22
|
timeouts,
|
|
22
23
|
silent: false, // Enable console logs for debugging
|
|
23
24
|
});
|