@springmicro/auth 0.1.8 → 0.2.0-alpha.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 +20 -15
- package/dist/Index-652aeb8c-BTQ1rBi7.js +2818 -0
- package/dist/Index-c419311f-BOZhAAW3.js +1054 -0
- package/dist/Web3Auth-hACKSouN.js +32769 -0
- package/dist/alphawallet-B7eovdf-.js +26 -0
- package/dist/apexwallet-ysP20G9D.js +93 -0
- package/dist/atoken-BBnNTzcz.js +27 -0
- package/dist/bifrostwallet-CNNBO92h.js +11 -0
- package/dist/binance-DvPgAzCw.js +14 -0
- package/dist/bitget-DZOUrwgy.js +4 -0
- package/dist/bitpie-C_uxmEzw.js +25 -0
- package/dist/bitski-DpzkHNkv.js +4 -0
- package/dist/blockwallet-BL69cqkA.js +8 -0
- package/dist/brave-DnRzMQYW.js +35 -0
- package/dist/ccip-c78d2f16-DLcRlwod.js +165 -0
- package/dist/coin98wallet-CkFdOvXt.js +4 -0
- package/dist/coinbase-CaGNx5if.js +9 -0
- package/dist/core-9rK8tWud.js +7 -0
- package/dist/defiwallet-0AsgJBSy.js +10 -0
- package/dist/detected-CX_JZaUk.js +6 -0
- package/dist/echooo-CmaetT_Z.js +14 -0
- package/dist/enkrypt-BibtwvK7.js +20 -0
- package/dist/exodus-BxzkDWWP.js +4 -0
- package/dist/fordefi-CvKyVwhI.js +6 -0
- package/dist/foxwallet-D7c_LDTf.js +4 -0
- package/dist/frame-CDfNmjUy.js +7 -0
- package/dist/frontier-DqKNSj2z.js +8 -0
- package/dist/huobiwallet-CxSwqa5L.js +14 -0
- package/dist/hyperpay-nmHE3WqM.js +7 -0
- package/dist/icon-2Zqy7pqQ.js +8 -0
- package/dist/icon-CGWI1Ies.js +43 -0
- package/dist/icon-C_O4nprO.js +9 -0
- package/dist/icon-DbgmZCnU.js +9 -0
- package/dist/icon-cAd7RhSC.js +9 -0
- package/dist/icon-duCa3gfT.js +11 -0
- package/dist/imtoken-yENtOTS3.js +17 -0
- package/dist/index-021f6a62-Zz543EDB.js +2583 -0
- package/dist/index-40a497ea-Bn2mC0r7.js +1010 -0
- package/dist/index-BHkXn9Ss.js +4010 -0
- package/dist/index-BaYEABY7.js +7089 -0
- package/dist/index-BtLU53lm.js +6023 -0
- package/dist/index-CynP9H3X.js +6188 -0
- package/dist/index-Dg8m-Szw.js +31 -0
- package/dist/index-Dt6M8ha9.js +161 -0
- package/dist/index-DtJfAdfq.js +5822 -0
- package/dist/index-klU8YB0c.js +1983 -0
- package/dist/index.d.ts +124 -0
- package/dist/index.js +5 -43
- package/dist/index.umd.cjs +1937 -1
- package/dist/infinitywallet-C8J4FUYw.js +42 -0
- package/dist/kayros-AIrUK1za.js +27 -0
- package/dist/lif3wallet-C5D6r8pg.js +41 -0
- package/dist/liquality-nbCtErVq.js +16 -0
- package/dist/mathwallet-CWkivCXo.js +50 -0
- package/dist/meetone-kKmvI8md.js +13 -0
- package/dist/metamask-BN7yiDV1.js +64 -0
- package/dist/mykey-CQZ6UcLH.js +13 -0
- package/dist/number-BXHWhlom.js +1529 -0
- package/dist/okxwallet-CJLVogh2.js +8 -0
- package/dist/oneInch-CciyZ4Pz.js +72 -0
- package/dist/onekey-Dal8kYjU.js +9 -0
- package/dist/opera-DnKg-TJU.js +24 -0
- package/dist/ownbit-BshJUVuW.js +18 -0
- package/dist/phantom-CJ8dIcov.js +35 -0
- package/dist/rabby-D4thTcd6.js +27 -0
- package/dist/rainbow-mXld6yWV.js +69 -0
- package/dist/roninwallet-ZyYrd-D1.js +9 -0
- package/dist/safeheron-Eg1Jb29V.js +23 -0
- package/dist/safepal-DVIKy94N.js +105 -0
- package/dist/sequence-BS2IbtDg.js +70 -0
- package/dist/stablewallet-jyB079Wb.js +20 -0
- package/dist/status-FrAvQjfn.js +4 -0
- package/dist/subwallet-DMvFqKyY.js +25 -0
- package/dist/talisman-Bp8zUXqB.js +16 -0
- package/dist/tallywallet-B4OS9nIr.js +16 -0
- package/dist/tokenary-C7jjcbQa.js +18 -0
- package/dist/tokenpocket-9ZRPmAFA.js +28 -0
- package/dist/tp-V2em5bdl.js +13 -0
- package/dist/transactionRequest-be6a8ea9-CUKWo5mx.js +1117 -0
- package/dist/trust-gPypS1O7.js +11 -0
- package/dist/xdefi-COVIyGz4.js +38 -0
- package/dist/zeal-DxHbDqm0.js +9 -0
- package/dist/zerion-BfW0UElc.js +8 -0
- package/dist/zodiacpilot-CrId6F4w.js +6 -0
- package/package.json +35 -15
- package/src/auth/config.ts +0 -2
- package/src/components/SignUp.tsx +442 -0
- package/src/components/forms/AgreementModal.tsx +88 -0
- package/src/components/forms/CaptchaController.tsx +94 -0
- package/src/components/forms/CaptchaModal.jsx +171 -0
- package/src/components/forms/CaptchaWidget.jsx +146 -0
- package/src/components/forms/PasswordChecker.ts +88 -0
- package/src/components/forms/SendCodeInput.tsx +149 -0
- package/src/components/forms/SignUpFormItem.tsx +704 -0
- package/src/components/forms/util/application-api.ts +155 -0
- package/src/components/forms/util/auth-api.ts +198 -0
- package/src/components/forms/util/auth-util.tsx +346 -0
- package/src/components/forms/util/core.ts +493 -0
- package/src/components/forms/util/invitation-api.ts +132 -0
- package/src/components/forms/util/provider.tsx +603 -0
- package/src/components/forms/util/user-api.ts +303 -0
- package/src/components/provider/AdfsLoginButton.jsx +38 -0
- package/src/components/provider/AlipayLoginButton.jsx +38 -0
- package/src/components/provider/AppleLoginButton.jsx +38 -0
- package/src/components/provider/AzureADB2CLoginButton.jsx +38 -0
- package/src/components/provider/AzureADLoginButton.jsx +38 -0
- package/src/components/provider/BaiduLoginButton.jsx +38 -0
- package/src/components/provider/BilibiliLoginButton.jsx +37 -0
- package/src/components/provider/CasdoorLoginButton.jsx +38 -0
- package/src/components/provider/DingTalkLoginButton.jsx +37 -0
- package/src/components/provider/DouyinLoginButton.jsx +38 -0
- package/src/components/provider/FacebookLoginButton.jsx +37 -0
- package/src/components/provider/GitHubLoginButton.jsx +37 -0
- package/src/components/provider/GitLabLoginButton.jsx +38 -0
- package/src/components/provider/GiteeLoginButton.jsx +34 -0
- package/src/components/provider/GoogleLoginButton.jsx +68 -0
- package/src/components/provider/InfoflowLoginButton.jsx +38 -0
- package/src/components/provider/LarkLoginButton.jsx +38 -0
- package/src/components/provider/LinkedInLoginButton.jsx +37 -0
- package/src/components/provider/LoginButton.jsx +33 -0
- package/src/components/provider/OktaLoginButton.jsx +38 -0
- package/src/components/provider/Provider.jsx +3 -0
- package/src/components/provider/ProviderButton.jsx +327 -0
- package/src/components/provider/QqLoginButton.jsx +31 -0
- package/src/components/provider/SelfLoginButton.jsx +47 -0
- package/src/components/provider/SlackLoginButton.jsx +38 -0
- package/src/components/provider/SteamLoginButton.jsx +38 -0
- package/src/components/provider/WeComLoginButton.jsx +34 -0
- package/src/components/provider/Web3Auth.jsx +365 -0
- package/src/components/provider/WechatLoginButton.jsx +37 -0
- package/src/components/provider/WeiboLoginButton.jsx +34 -0
- package/src/components/util.tsx +173 -0
- package/src/i18n/en/signup.json +48 -0
- package/src/i18n/index.ts +17 -0
- package/src/index.tsx +6 -1
- package/vite.config.ts +33 -25
|
@@ -0,0 +1,365 @@
|
|
|
1
|
+
// // Copyright 2023 The Casdoor Authors. All Rights Reserved.
|
|
2
|
+
// //
|
|
3
|
+
// // Licensed under the Apache License, Version 2.0 (the "License");
|
|
4
|
+
// // you may not use this file except in compliance with the License.
|
|
5
|
+
// // You may obtain a copy of the License at
|
|
6
|
+
// //
|
|
7
|
+
// // http://www.apache.org/licenses/LICENSE-2.0
|
|
8
|
+
// //
|
|
9
|
+
// // Unless required by applicable law or agreed to in writing, software
|
|
10
|
+
// // distributed under the License is distributed on an "AS IS" BASIS,
|
|
11
|
+
// // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
12
|
+
// // See the License for the specific language governing permissions and
|
|
13
|
+
// // limitations under the License.
|
|
14
|
+
|
|
15
|
+
import * as Setting from "../forms/util/core";
|
|
16
|
+
|
|
17
|
+
import i18next from "i18next";
|
|
18
|
+
import { v4 as uuidv4 } from "uuid";
|
|
19
|
+
import {
|
|
20
|
+
SignTypedDataVersion,
|
|
21
|
+
recoverTypedSignature,
|
|
22
|
+
} from "@metamask/eth-sig-util";
|
|
23
|
+
import { getAuthUrl } from "../forms/util/provider";
|
|
24
|
+
import { Buffer } from "buffer";
|
|
25
|
+
import Onboard from "@web3-onboard/core";
|
|
26
|
+
import injectedModule from "@web3-onboard/injected-wallets";
|
|
27
|
+
import infinityWalletModule from "@web3-onboard/infinity-wallet";
|
|
28
|
+
// import sequenceModule from "@web3-onboard/sequence";
|
|
29
|
+
import trustModule from "@web3-onboard/trust";
|
|
30
|
+
import frontierModule from "@web3-onboard/frontier";
|
|
31
|
+
import tahoModule from "@web3-onboard/taho";
|
|
32
|
+
import coinbaseModule from "@web3-onboard/coinbase";
|
|
33
|
+
import gnosisModule from "@web3-onboard/gnosis";
|
|
34
|
+
// import keystoneModule from "@web3-onboard/keystone";
|
|
35
|
+
// import keepkeyModule from "@web3-onboard/keepkey";
|
|
36
|
+
// import dcentModule from "@web3-onboard/dcent";
|
|
37
|
+
// import ledgerModule from "@web3-onboard/ledger";
|
|
38
|
+
// import trezorModule from "@web3-onboard/trezor";
|
|
39
|
+
// import walletConnectModule from "@web3-onboard/walletconnect";
|
|
40
|
+
// import fortmaticModule from "@web3-onboard/fortmatic";
|
|
41
|
+
// import portisModule from "@web3-onboard/portis";
|
|
42
|
+
// import magicModule from "@web3-onboard/magic";
|
|
43
|
+
|
|
44
|
+
global.Buffer = Buffer;
|
|
45
|
+
|
|
46
|
+
export function generateNonce() {
|
|
47
|
+
const nonce = uuidv4();
|
|
48
|
+
return nonce;
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
export function getWeb3AuthTokenKey(address) {
|
|
52
|
+
return `Web3AuthToken_${address}`;
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
export function setWeb3AuthToken(token) {
|
|
56
|
+
const key = getWeb3AuthTokenKey(token.address);
|
|
57
|
+
localStorage.setItem(key, JSON.stringify(token));
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
export function getWeb3AuthToken(address) {
|
|
61
|
+
const key = getWeb3AuthTokenKey(address);
|
|
62
|
+
return JSON.parse(localStorage.getItem(key));
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
export function delWeb3AuthToken(address) {
|
|
66
|
+
const key = getWeb3AuthTokenKey(address);
|
|
67
|
+
localStorage.removeItem(key);
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
export function clearWeb3AuthToken() {
|
|
71
|
+
const keys = Object.keys(localStorage);
|
|
72
|
+
keys.forEach((key) => {
|
|
73
|
+
if (key.startsWith("Web3AuthToken_")) {
|
|
74
|
+
localStorage.removeItem(key);
|
|
75
|
+
}
|
|
76
|
+
});
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
export function detectMetaMaskPlugin() {
|
|
80
|
+
// check if ethereum extension MetaMask is installed
|
|
81
|
+
return window.ethereum && window.ethereum.isMetaMask;
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
export function requestEthereumAccount() {
|
|
85
|
+
const method = "eth_requestAccounts";
|
|
86
|
+
const selectedAccount = window.ethereum
|
|
87
|
+
.request({ method })
|
|
88
|
+
.then((accounts) => {
|
|
89
|
+
return accounts[0];
|
|
90
|
+
});
|
|
91
|
+
return selectedAccount;
|
|
92
|
+
}
|
|
93
|
+
|
|
94
|
+
export function signEthereumTypedData(from, nonce) {
|
|
95
|
+
// https://docs.metamask.io/wallet/how-to/sign-data/
|
|
96
|
+
const date = new Date();
|
|
97
|
+
const typedData = JSON.stringify({
|
|
98
|
+
domain: {
|
|
99
|
+
chainId: window.ethereum.chainId,
|
|
100
|
+
name: "Casdoor",
|
|
101
|
+
version: "1",
|
|
102
|
+
},
|
|
103
|
+
message: {
|
|
104
|
+
prompt:
|
|
105
|
+
"In order to authenticate to this website, sign this request and your public address will be sent to the server in a verifiable way.",
|
|
106
|
+
nonce: nonce,
|
|
107
|
+
createAt: `${date.toLocaleString()}`,
|
|
108
|
+
},
|
|
109
|
+
primaryType: "AuthRequest",
|
|
110
|
+
types: {
|
|
111
|
+
EIP712Domain: [
|
|
112
|
+
{ name: "name", type: "string" },
|
|
113
|
+
{ name: "version", type: "string" },
|
|
114
|
+
{ name: "chainId", type: "uint256" },
|
|
115
|
+
],
|
|
116
|
+
AuthRequest: [
|
|
117
|
+
{ name: "prompt", type: "string" },
|
|
118
|
+
{ name: "nonce", type: "string" },
|
|
119
|
+
{ name: "createAt", type: "string" },
|
|
120
|
+
],
|
|
121
|
+
},
|
|
122
|
+
});
|
|
123
|
+
|
|
124
|
+
const method = "eth_signTypedData_v4";
|
|
125
|
+
const params = [from, typedData];
|
|
126
|
+
|
|
127
|
+
return window.ethereum.request({ method, params }).then((sign) => {
|
|
128
|
+
return {
|
|
129
|
+
address: from,
|
|
130
|
+
createAt: Math.floor(date.getTime() / 1000),
|
|
131
|
+
typedData: typedData,
|
|
132
|
+
signature: sign,
|
|
133
|
+
};
|
|
134
|
+
});
|
|
135
|
+
}
|
|
136
|
+
|
|
137
|
+
export function checkEthereumSignedTypedData(token) {
|
|
138
|
+
if (token === undefined || token === null) {
|
|
139
|
+
return false;
|
|
140
|
+
}
|
|
141
|
+
if (token.address && token.typedData && token.signature) {
|
|
142
|
+
const recoveredAddr = recoverTypedSignature({
|
|
143
|
+
data: JSON.parse(token.typedData),
|
|
144
|
+
signature: token.signature,
|
|
145
|
+
version: SignTypedDataVersion.V4,
|
|
146
|
+
});
|
|
147
|
+
// const recoveredAddr = token.address;
|
|
148
|
+
return recoveredAddr === token.address;
|
|
149
|
+
// return toChecksumAddress(recoveredAddr) === toChecksumAddress(token.address);
|
|
150
|
+
}
|
|
151
|
+
return false;
|
|
152
|
+
}
|
|
153
|
+
|
|
154
|
+
export async function authViaMetaMask(application, provider, method) {
|
|
155
|
+
if (!detectMetaMaskPlugin()) {
|
|
156
|
+
Setting.showMessage(
|
|
157
|
+
"error",
|
|
158
|
+
`${i18next.t("login:MetaMask plugin not detected")}`
|
|
159
|
+
);
|
|
160
|
+
return;
|
|
161
|
+
}
|
|
162
|
+
try {
|
|
163
|
+
const account = await requestEthereumAccount();
|
|
164
|
+
let token = getWeb3AuthToken(account);
|
|
165
|
+
if (!checkEthereumSignedTypedData(token)) {
|
|
166
|
+
const nonce = generateNonce();
|
|
167
|
+
token = await signEthereumTypedData(account, nonce);
|
|
168
|
+
setWeb3AuthToken(token);
|
|
169
|
+
}
|
|
170
|
+
const redirectUri = `${getAuthUrl(
|
|
171
|
+
application,
|
|
172
|
+
provider,
|
|
173
|
+
method
|
|
174
|
+
)}&web3AuthTokenKey=${getWeb3AuthTokenKey(account)}`;
|
|
175
|
+
Setting.goToLink(redirectUri);
|
|
176
|
+
} catch (err) {
|
|
177
|
+
Setting.showMessage(
|
|
178
|
+
"error",
|
|
179
|
+
`${i18next.t("login:Failed to obtain MetaMask authorization")}: ${
|
|
180
|
+
err.message
|
|
181
|
+
}`
|
|
182
|
+
);
|
|
183
|
+
}
|
|
184
|
+
}
|
|
185
|
+
|
|
186
|
+
const web3Wallets = {
|
|
187
|
+
// injected wallets
|
|
188
|
+
injected: {
|
|
189
|
+
label: "Injected",
|
|
190
|
+
wallet: injectedModule(),
|
|
191
|
+
},
|
|
192
|
+
// sdk wallets
|
|
193
|
+
coinbase: {
|
|
194
|
+
label: "Coinbase",
|
|
195
|
+
wallet: coinbaseModule(),
|
|
196
|
+
},
|
|
197
|
+
trust: {
|
|
198
|
+
label: "Trust",
|
|
199
|
+
wallet: trustModule(),
|
|
200
|
+
},
|
|
201
|
+
gnosis: {
|
|
202
|
+
label: "Gnosis",
|
|
203
|
+
wallet: gnosisModule(),
|
|
204
|
+
},
|
|
205
|
+
// Broken
|
|
206
|
+
// sequence: {
|
|
207
|
+
// label: "Sequence",
|
|
208
|
+
// wallet: sequenceModule(),
|
|
209
|
+
// },
|
|
210
|
+
taho: {
|
|
211
|
+
label: "Taho",
|
|
212
|
+
wallet: tahoModule(),
|
|
213
|
+
},
|
|
214
|
+
frontier: {
|
|
215
|
+
label: "Frontier",
|
|
216
|
+
wallet: frontierModule(),
|
|
217
|
+
},
|
|
218
|
+
infinityWallet: {
|
|
219
|
+
label: "Infinity Wallet",
|
|
220
|
+
wallet: infinityWalletModule(),
|
|
221
|
+
},
|
|
222
|
+
// hardware wallets
|
|
223
|
+
// keystone: {
|
|
224
|
+
// label: "Keystone",
|
|
225
|
+
// wallet: keystoneModule(),
|
|
226
|
+
// },
|
|
227
|
+
// keepkey: {
|
|
228
|
+
// label: "KeepKey",
|
|
229
|
+
// wallet: keepkeyModule(),
|
|
230
|
+
// },
|
|
231
|
+
// dcent: {
|
|
232
|
+
// label: "D'CENT",
|
|
233
|
+
// wallet: dcentModule(),
|
|
234
|
+
// },
|
|
235
|
+
|
|
236
|
+
// some wallet need custome `apiKey` or `projectId` configure item
|
|
237
|
+
// const magic = magicModule({
|
|
238
|
+
// apiKey: "magicApiKey",
|
|
239
|
+
// });
|
|
240
|
+
// const fortmatic = fortmaticModule({
|
|
241
|
+
// apiKey: "fortmaticApiKey",
|
|
242
|
+
// });
|
|
243
|
+
// const portis = portisModule({
|
|
244
|
+
// apiKey: "portisApiKey",
|
|
245
|
+
// });
|
|
246
|
+
// const ledger = ledgerModule({
|
|
247
|
+
// projectId: "ledgerProjectId"
|
|
248
|
+
// });
|
|
249
|
+
// const walletConnect = walletConnectModule({
|
|
250
|
+
// projectId: "walletConnectProjectId",
|
|
251
|
+
// });
|
|
252
|
+
};
|
|
253
|
+
|
|
254
|
+
export function getWeb3OnboardWalletsOptions() {
|
|
255
|
+
return Object.entries(web3Wallets).map(([key, value]) => ({
|
|
256
|
+
label: value.label,
|
|
257
|
+
value: key,
|
|
258
|
+
}));
|
|
259
|
+
}
|
|
260
|
+
|
|
261
|
+
function getWeb3OnboardWallets(options) {
|
|
262
|
+
if (options === null || options === undefined || !Array.isArray(options)) {
|
|
263
|
+
return [];
|
|
264
|
+
}
|
|
265
|
+
return options.map((walletType) => {
|
|
266
|
+
if (walletType && web3Wallets[walletType]?.wallet) {
|
|
267
|
+
return web3Wallets[walletType]?.wallet;
|
|
268
|
+
}
|
|
269
|
+
});
|
|
270
|
+
}
|
|
271
|
+
|
|
272
|
+
export function initWeb3Onboard(application, provider) {
|
|
273
|
+
// init wallet
|
|
274
|
+
// options = ["injected","coinbase",...]
|
|
275
|
+
const options = JSON.parse(provider.metadata);
|
|
276
|
+
const wallets = getWeb3OnboardWallets(options);
|
|
277
|
+
|
|
278
|
+
// init chain
|
|
279
|
+
// const InfuraKey = "2fa45cbe531e4e65be4fcbf408e651a8";
|
|
280
|
+
const chains = [
|
|
281
|
+
// {
|
|
282
|
+
// id: "0x1",
|
|
283
|
+
// token: "ETH",
|
|
284
|
+
// label: "Ethereum Mainnet",
|
|
285
|
+
// rpcUrl: `https://mainnet.infura.io/v3/${InfuraKey}`,
|
|
286
|
+
// },
|
|
287
|
+
// {
|
|
288
|
+
// id: "0x5",
|
|
289
|
+
// token: "ETH",
|
|
290
|
+
// label: "Goerli",
|
|
291
|
+
// rpcUrl: `https://goerli.infura.io/v3/${InfuraKey}`,
|
|
292
|
+
// },
|
|
293
|
+
{
|
|
294
|
+
id: "0x13881",
|
|
295
|
+
token: "MATIC",
|
|
296
|
+
label: "Polygon - Mumbai",
|
|
297
|
+
rpcUrl: "https://matic-mumbai.chainstacklabs.com",
|
|
298
|
+
},
|
|
299
|
+
{
|
|
300
|
+
id: "0x38",
|
|
301
|
+
token: "BNB",
|
|
302
|
+
label: "Binance",
|
|
303
|
+
rpcUrl: "https://bsc-dataseed.binance.org/",
|
|
304
|
+
},
|
|
305
|
+
{
|
|
306
|
+
id: "0xA",
|
|
307
|
+
token: "OETH",
|
|
308
|
+
label: "Optimism",
|
|
309
|
+
rpcUrl: "https://mainnet.optimism.io",
|
|
310
|
+
},
|
|
311
|
+
{
|
|
312
|
+
id: "0xA4B1",
|
|
313
|
+
token: "ARB-ETH",
|
|
314
|
+
label: "Arbitrum",
|
|
315
|
+
rpcUrl: "https://rpc.ankr.com/arbitrum",
|
|
316
|
+
},
|
|
317
|
+
];
|
|
318
|
+
|
|
319
|
+
const appMetadata = {
|
|
320
|
+
name: "Casdoor",
|
|
321
|
+
description: "Connect a wallet using Casdoor",
|
|
322
|
+
recommendedInjectedWallets: [
|
|
323
|
+
{ name: "MetaMask", url: "https://metamask.io" },
|
|
324
|
+
{ name: "Coinbase", url: "https://www.coinbase.com/wallet" },
|
|
325
|
+
],
|
|
326
|
+
};
|
|
327
|
+
|
|
328
|
+
const web3Onboard = Onboard({
|
|
329
|
+
wallets,
|
|
330
|
+
chains,
|
|
331
|
+
appMetadata,
|
|
332
|
+
});
|
|
333
|
+
return web3Onboard;
|
|
334
|
+
}
|
|
335
|
+
|
|
336
|
+
export async function authViaWeb3Onboard(application, provider, method) {
|
|
337
|
+
try {
|
|
338
|
+
const onboard = initWeb3Onboard(application, provider);
|
|
339
|
+
const connectedWallets = await onboard.connectWallet();
|
|
340
|
+
if (connectedWallets.length > 0) {
|
|
341
|
+
const wallet = connectedWallets[0];
|
|
342
|
+
const account = wallet.accounts[0];
|
|
343
|
+
const address = account.address;
|
|
344
|
+
const token = {
|
|
345
|
+
address: address, // e.g."0xbd5444d31fe4139ee36bea29e43d4ac67ae276de"
|
|
346
|
+
walletType: wallet.label, // e.g."MetaMask"
|
|
347
|
+
createAt: Math.floor(new Date().getTime() / 1000),
|
|
348
|
+
};
|
|
349
|
+
setWeb3AuthToken(token);
|
|
350
|
+
const redirectUri = `${getAuthUrl(
|
|
351
|
+
application,
|
|
352
|
+
provider,
|
|
353
|
+
method
|
|
354
|
+
)}&web3AuthTokenKey=${getWeb3AuthTokenKey(address)}`;
|
|
355
|
+
Setting.goToLink(redirectUri);
|
|
356
|
+
}
|
|
357
|
+
} catch (err) {
|
|
358
|
+
Setting.showMessage(
|
|
359
|
+
"error",
|
|
360
|
+
`${i18next.t(
|
|
361
|
+
"login:Failed to obtain Web3-Onboard authorization"
|
|
362
|
+
)}: ${err}`
|
|
363
|
+
);
|
|
364
|
+
}
|
|
365
|
+
}
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
// Copyright 2021 The Casdoor Authors. All Rights Reserved.
|
|
2
|
+
//
|
|
3
|
+
// Licensed under the Apache License, Version 2.0 (the "License");
|
|
4
|
+
// you may not use this file except in compliance with the License.
|
|
5
|
+
// You may obtain a copy of the License at
|
|
6
|
+
//
|
|
7
|
+
// http://www.apache.org/licenses/LICENSE-2.0
|
|
8
|
+
//
|
|
9
|
+
// Unless required by applicable law or agreed to in writing, software
|
|
10
|
+
// distributed under the License is distributed on an "AS IS" BASIS,
|
|
11
|
+
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
12
|
+
// See the License for the specific language governing permissions and
|
|
13
|
+
// limitations under the License.
|
|
14
|
+
|
|
15
|
+
import { createButton } from "react-social-login-buttons";
|
|
16
|
+
import { StaticBaseUrl } from "../forms/util/core";
|
|
17
|
+
|
|
18
|
+
function Icon({ width = 24, height = 24, color }) {
|
|
19
|
+
return (
|
|
20
|
+
<img
|
|
21
|
+
src={`${StaticBaseUrl}/buttons/wechat.svg`}
|
|
22
|
+
alt="Sign in with Wechat"
|
|
23
|
+
/>
|
|
24
|
+
);
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
const config = {
|
|
28
|
+
text: "Sign in with Wechat",
|
|
29
|
+
icon: Icon,
|
|
30
|
+
iconFormat: (name) => `fa fa-${name}`,
|
|
31
|
+
style: { background: "rgb(0,194,80)" },
|
|
32
|
+
activeStyle: { background: "rgb(0,158,64)" },
|
|
33
|
+
};
|
|
34
|
+
|
|
35
|
+
const WechatLoginButton = createButton(config);
|
|
36
|
+
|
|
37
|
+
export default WechatLoginButton;
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
// Copyright 2021 The Casdoor Authors. All Rights Reserved.
|
|
2
|
+
//
|
|
3
|
+
// Licensed under the Apache License, Version 2.0 (the "License");
|
|
4
|
+
// you may not use this file except in compliance with the License.
|
|
5
|
+
// You may obtain a copy of the License at
|
|
6
|
+
//
|
|
7
|
+
// http://www.apache.org/licenses/LICENSE-2.0
|
|
8
|
+
//
|
|
9
|
+
// Unless required by applicable law or agreed to in writing, software
|
|
10
|
+
// distributed under the License is distributed on an "AS IS" BASIS,
|
|
11
|
+
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
12
|
+
// See the License for the specific language governing permissions and
|
|
13
|
+
// limitations under the License.
|
|
14
|
+
|
|
15
|
+
import { createButton } from "react-social-login-buttons";
|
|
16
|
+
import { StaticBaseUrl } from "../forms/util/core";
|
|
17
|
+
|
|
18
|
+
function Icon({ width = 24, height = 24, color }) {
|
|
19
|
+
return (
|
|
20
|
+
<img src={`${StaticBaseUrl}/buttons/weibo.svg`} alt="Sign in with Weibo" />
|
|
21
|
+
);
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
const config = {
|
|
25
|
+
text: "Sign in with Weibo",
|
|
26
|
+
icon: Icon,
|
|
27
|
+
iconFormat: (name) => `fa fa-${name}`,
|
|
28
|
+
style: { background: "#e62329" },
|
|
29
|
+
activeStyle: { background: "#e54329" },
|
|
30
|
+
};
|
|
31
|
+
|
|
32
|
+
const WeiboLoginButton = createButton(config);
|
|
33
|
+
|
|
34
|
+
export default WeiboLoginButton;
|
|
@@ -0,0 +1,173 @@
|
|
|
1
|
+
import React from "react";
|
|
2
|
+
|
|
3
|
+
export type SignupItem = {
|
|
4
|
+
name: string;
|
|
5
|
+
label: string;
|
|
6
|
+
placeholder: string;
|
|
7
|
+
prompted: boolean;
|
|
8
|
+
required: boolean;
|
|
9
|
+
rule: string;
|
|
10
|
+
visible: boolean;
|
|
11
|
+
};
|
|
12
|
+
|
|
13
|
+
export function getIcon(
|
|
14
|
+
signupItem: SignupItem,
|
|
15
|
+
options: {
|
|
16
|
+
password: {
|
|
17
|
+
state: Record<string, boolean>;
|
|
18
|
+
setState: React.Dispatch<React.SetStateAction<Record<string, boolean>>>;
|
|
19
|
+
};
|
|
20
|
+
},
|
|
21
|
+
Button: React.JSX.ElementType
|
|
22
|
+
) {
|
|
23
|
+
const eye = (
|
|
24
|
+
<svg
|
|
25
|
+
xmlns="http://www.w3.org/2000/svg"
|
|
26
|
+
width="24"
|
|
27
|
+
height="24"
|
|
28
|
+
viewBox="0 0 24 24"
|
|
29
|
+
fill="none"
|
|
30
|
+
stroke="currentColor"
|
|
31
|
+
stroke-width="2"
|
|
32
|
+
stroke-linecap="round"
|
|
33
|
+
stroke-linejoin="round"
|
|
34
|
+
className="lucide lucide-eye"
|
|
35
|
+
>
|
|
36
|
+
<path d="M2 12s3-7 10-7 10 7 10 7-3 7-10 7-10-7-10-7Z" />
|
|
37
|
+
<circle cx="12" cy="12" r="3" />
|
|
38
|
+
</svg>
|
|
39
|
+
);
|
|
40
|
+
const eyeOff = (
|
|
41
|
+
<svg
|
|
42
|
+
xmlns="http://www.w3.org/2000/svg"
|
|
43
|
+
width="24"
|
|
44
|
+
height="24"
|
|
45
|
+
viewBox="0 0 24 24"
|
|
46
|
+
fill="none"
|
|
47
|
+
stroke="currentColor"
|
|
48
|
+
stroke-width="2"
|
|
49
|
+
stroke-linecap="round"
|
|
50
|
+
stroke-linejoin="round"
|
|
51
|
+
className="lucide lucide-eye-off"
|
|
52
|
+
>
|
|
53
|
+
<path d="M9.88 9.88a3 3 0 1 0 4.24 4.24" />
|
|
54
|
+
<path d="M10.73 5.08A10.43 10.43 0 0 1 12 5c7 0 10 7 10 7a13.16 13.16 0 0 1-1.67 2.68" />
|
|
55
|
+
<path d="M6.61 6.61A13.526 13.526 0 0 0 2 12s3 7 10 7a9.74 9.74 0 0 0 5.39-1.61" />
|
|
56
|
+
<line x1="2" x2="22" y1="2" y2="22" />
|
|
57
|
+
</svg>
|
|
58
|
+
);
|
|
59
|
+
const type = getType(signupItem);
|
|
60
|
+
const key = getKey(signupItem);
|
|
61
|
+
if (type === "password") {
|
|
62
|
+
const showPassword = options.password.state[key];
|
|
63
|
+
return (
|
|
64
|
+
<Button
|
|
65
|
+
variant="ghost"
|
|
66
|
+
size="icon"
|
|
67
|
+
className="absolute top-1/2 right-2 -translate-y-1/2"
|
|
68
|
+
onClick={(e) => {
|
|
69
|
+
e.preventDefault();
|
|
70
|
+
e.stopPropagation();
|
|
71
|
+
options.password.setState({
|
|
72
|
+
...options.password.state,
|
|
73
|
+
[key]: !showPassword,
|
|
74
|
+
});
|
|
75
|
+
}}
|
|
76
|
+
>
|
|
77
|
+
{showPassword ? eyeOff : eye}
|
|
78
|
+
<span className="sr-only">Toggle password visibility</span>
|
|
79
|
+
</Button>
|
|
80
|
+
);
|
|
81
|
+
} else {
|
|
82
|
+
return null;
|
|
83
|
+
}
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
export function getKey(signupItem: SignupItem) {
|
|
87
|
+
const nameMap = {
|
|
88
|
+
ID: "id",
|
|
89
|
+
Username: "username",
|
|
90
|
+
// also firstName, lastName
|
|
91
|
+
"Display name": "name",
|
|
92
|
+
Affiliation: "affiliation",
|
|
93
|
+
"ID card": "idCard",
|
|
94
|
+
Email: "email",
|
|
95
|
+
Phone: "phone",
|
|
96
|
+
Password: "password",
|
|
97
|
+
"Confirm password": "confirm",
|
|
98
|
+
"Invitation code": "invitationCode",
|
|
99
|
+
"Country/Region": "country_region",
|
|
100
|
+
Agreement: "agreement",
|
|
101
|
+
};
|
|
102
|
+
if (Object.keys(nameMap).includes(signupItem.name)) {
|
|
103
|
+
return nameMap[signupItem.name];
|
|
104
|
+
} else {
|
|
105
|
+
return signupItem.name;
|
|
106
|
+
}
|
|
107
|
+
}
|
|
108
|
+
|
|
109
|
+
export function getType(
|
|
110
|
+
signupItem: SignupItem,
|
|
111
|
+
options?: { hidePassword: Record<string, boolean> }
|
|
112
|
+
) {
|
|
113
|
+
const password = ["password", "confirm"];
|
|
114
|
+
const key = getKey(signupItem);
|
|
115
|
+
if (password.includes(key) && !options?.hidePassword[key]) {
|
|
116
|
+
return "password";
|
|
117
|
+
} else {
|
|
118
|
+
return "text";
|
|
119
|
+
}
|
|
120
|
+
}
|
|
121
|
+
|
|
122
|
+
export function getPasswordVisibilityRecord(
|
|
123
|
+
signupItems: SignupItem[]
|
|
124
|
+
): Record<string, boolean> {
|
|
125
|
+
return Object.fromEntries(
|
|
126
|
+
signupItems
|
|
127
|
+
.filter((item) => getType(item) === "password")
|
|
128
|
+
.map((item) => [getKey(item), false])
|
|
129
|
+
);
|
|
130
|
+
}
|
|
131
|
+
|
|
132
|
+
export function getFormProps(signupItem: SignupItem) {
|
|
133
|
+
return {
|
|
134
|
+
name: getKey(signupItem),
|
|
135
|
+
label: signupItem.label || signupItem.name,
|
|
136
|
+
placeholder: signupItem.placeholder,
|
|
137
|
+
required: signupItem.required,
|
|
138
|
+
type: getType(signupItem),
|
|
139
|
+
};
|
|
140
|
+
}
|
|
141
|
+
|
|
142
|
+
export function getZod(z: any, signupItem: SignupItem) {
|
|
143
|
+
const key = getKey(signupItem);
|
|
144
|
+
let validator: any = z.string();
|
|
145
|
+
if (key === "email") {
|
|
146
|
+
validator = validator.email();
|
|
147
|
+
}
|
|
148
|
+
if (!signupItem.required) {
|
|
149
|
+
validator = validator.optional();
|
|
150
|
+
}
|
|
151
|
+
return validator;
|
|
152
|
+
}
|
|
153
|
+
|
|
154
|
+
export function getDefaultValues(signupItems: SignupItem[]) {
|
|
155
|
+
const entries = signupItems.map((item) => {
|
|
156
|
+
return [getKey(item), ""];
|
|
157
|
+
});
|
|
158
|
+
// add codes
|
|
159
|
+
const codes = signupItems
|
|
160
|
+
.filter((item) => requiresCode(item))
|
|
161
|
+
.map((item) => {
|
|
162
|
+
return [getKey(item) + "Code", ""];
|
|
163
|
+
});
|
|
164
|
+
return Object.fromEntries([...entries, ...codes]);
|
|
165
|
+
}
|
|
166
|
+
|
|
167
|
+
export function requiresCode(signupItem: SignupItem) {
|
|
168
|
+
const key = getKey(signupItem);
|
|
169
|
+
return (
|
|
170
|
+
(key === "email" || key === "phone") &&
|
|
171
|
+
signupItem.rule !== "No verification"
|
|
172
|
+
);
|
|
173
|
+
}
|
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
{
|
|
2
|
+
"translation": {
|
|
3
|
+
"signup": {
|
|
4
|
+
"username": "Username",
|
|
5
|
+
"confirm": "Confirm password",
|
|
6
|
+
"signInNow": "Sign In Now",
|
|
7
|
+
"signUp": "Sign Up",
|
|
8
|
+
"haveAccount": "Have account?"
|
|
9
|
+
},
|
|
10
|
+
"forget": {
|
|
11
|
+
"username": "Please input your username.",
|
|
12
|
+
"firstName": "Please input your first name.",
|
|
13
|
+
"lastName": "Please input your last name.",
|
|
14
|
+
"realName": "Please input your real name.",
|
|
15
|
+
"displayName": "Please input your display name.",
|
|
16
|
+
"affliation": "Please input your affliation.",
|
|
17
|
+
"idCard": "Please input your ID card number.",
|
|
18
|
+
"code": "Please input your verification code.",
|
|
19
|
+
"email": "Please input your email.",
|
|
20
|
+
"confirm": "Please confirm your password and ensure it matches.",
|
|
21
|
+
"invitationCode": "Please input your invitation code."
|
|
22
|
+
},
|
|
23
|
+
"format": {
|
|
24
|
+
"idCard": "The ID card number format is incorrect."
|
|
25
|
+
},
|
|
26
|
+
"general": {
|
|
27
|
+
"firstName": "First name",
|
|
28
|
+
"lastName": "Last name",
|
|
29
|
+
"displayName": "Display name",
|
|
30
|
+
"realName": "Real name",
|
|
31
|
+
"email": "Email",
|
|
32
|
+
"password": "Password",
|
|
33
|
+
"captcha": "Captcha"
|
|
34
|
+
},
|
|
35
|
+
"user": {
|
|
36
|
+
"affliation": "Affliation",
|
|
37
|
+
"idCard": "ID card"
|
|
38
|
+
},
|
|
39
|
+
"code": {
|
|
40
|
+
"email": "Email code",
|
|
41
|
+
"sending": "Sending",
|
|
42
|
+
"sendCode": "Send code"
|
|
43
|
+
},
|
|
44
|
+
"application": {
|
|
45
|
+
"invitationCode": "Invitation code"
|
|
46
|
+
}
|
|
47
|
+
}
|
|
48
|
+
}
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
import i18n from "i18next";
|
|
2
|
+
// import detector from "i18next-browser-languagedetector";
|
|
3
|
+
import { initReactI18next } from "react-i18next";
|
|
4
|
+
import en from "./en/signup.json";
|
|
5
|
+
|
|
6
|
+
i18n
|
|
7
|
+
// .use(detector)
|
|
8
|
+
.use(initReactI18next) // passes i18n down to react-i18next
|
|
9
|
+
.init({
|
|
10
|
+
lng: "en",
|
|
11
|
+
fallbackLng: "en", // use en if detected lng is not available
|
|
12
|
+
resources: {
|
|
13
|
+
en,
|
|
14
|
+
},
|
|
15
|
+
});
|
|
16
|
+
|
|
17
|
+
export default i18n;
|
package/src/index.tsx
CHANGED
|
@@ -1,3 +1,8 @@
|
|
|
1
1
|
import getAuthConfig from "./auth/config";
|
|
2
|
+
import { SignUp, useSignUp, SignUpProvider } from "./components/SignUp";
|
|
2
3
|
|
|
3
|
-
|
|
4
|
+
// function SignUp() {
|
|
5
|
+
// return <>Sign up</>;
|
|
6
|
+
// }
|
|
7
|
+
|
|
8
|
+
export { getAuthConfig, SignUp, useSignUp, SignUpProvider };
|