@web3auth/auth-adapter
Version:
Auth adapter for Web3auth
258 lines (253 loc) • 11.6 kB
JavaScript
'use strict';
var _objectSpread = require('@babel/runtime/helpers/objectSpread2');
var _defineProperty = require('@babel/runtime/helpers/defineProperty');
var auth = require('@web3auth/auth');
var base = require('@web3auth/base');
var deepmerge = require('deepmerge');
var config = require('./config.js');
class AuthAdapter extends base.BaseAdapter {
constructor(params = {}) {
super(params);
_defineProperty(this, "name", base.WALLET_ADAPTERS.AUTH);
_defineProperty(this, "adapterNamespace", base.ADAPTER_NAMESPACES.MULTICHAIN);
_defineProperty(this, "type", base.ADAPTER_CATEGORY.IN_APP);
_defineProperty(this, "authInstance", null);
_defineProperty(this, "status", base.ADAPTER_STATUS.NOT_READY);
_defineProperty(this, "currentChainNamespace", base.CHAIN_NAMESPACES.EIP155);
_defineProperty(this, "privateKeyProvider", null);
_defineProperty(this, "authOptions", void 0);
_defineProperty(this, "loginSettings", {
loginProvider: ""
});
this.setAdapterSettings(_objectSpread(_objectSpread({}, params.adapterSettings), {}, {
chainConfig: params.chainConfig,
clientId: params.clientId || "",
sessionTime: params.sessionTime,
web3AuthNetwork: params.web3AuthNetwork,
useCoreKitKey: params.useCoreKitKey,
privateKeyProvider: params.privateKeyProvider
}));
this.loginSettings = params.loginSettings || {
loginProvider: ""
};
this.privateKeyProvider = params.privateKeyProvider || null;
}
get chainConfigProxy() {
return this.chainConfig ? _objectSpread({}, this.chainConfig) : null;
}
get provider() {
if (this.status !== base.ADAPTER_STATUS.NOT_READY && this.privateKeyProvider) {
return this.privateKeyProvider;
}
return null;
}
set provider(_) {
throw new Error("Not implemented");
}
async init(options) {
super.checkInitializationRequirements();
if (!this.clientId) throw base.WalletInitializationError.invalidParams("clientId is required before auth's initialization");
if (!this.authOptions) throw base.WalletInitializationError.invalidParams("authOptions is required before auth's initialization");
const isRedirectResult = this.authOptions.uxMode === auth.UX_MODE.REDIRECT;
this.authOptions = _objectSpread(_objectSpread({}, this.authOptions), {}, {
replaceUrlOnRedirect: isRedirectResult,
useCoreKitKey: this.useCoreKitKey
});
this.authInstance = new auth.Auth(_objectSpread(_objectSpread({}, this.authOptions), {}, {
clientId: this.clientId,
network: this.authOptions.network || this.web3AuthNetwork || auth.WEB3AUTH_NETWORK.SAPPHIRE_MAINNET
}));
base.log.debug("initializing auth adapter init");
await this.authInstance.init();
if (!this.chainConfig) throw base.WalletInitializationError.invalidParams("chainConfig is required before initialization");
this.status = base.ADAPTER_STATUS.READY;
this.emit(base.ADAPTER_EVENTS.READY, base.WALLET_ADAPTERS.AUTH);
try {
base.log.debug("initializing auth adapter");
const finalPrivKey = this._getFinalPrivKey();
// connect only if it is redirect result or if connect (adapter is cached/already connected in same session) is true
if (finalPrivKey && (options.autoConnect || isRedirectResult)) {
this.rehydrated = true;
await this.connect();
}
} catch (error) {
base.log.error("Failed to connect with cached auth provider", error);
this.emit(base.ADAPTER_EVENTS.ERRORED, error);
}
}
async connect(params = {
loginProvider: ""
}) {
super.checkConnectionRequirements();
this.status = base.ADAPTER_STATUS.CONNECTING;
this.emit(base.ADAPTER_EVENTS.CONNECTING, _objectSpread(_objectSpread({}, params), {}, {
adapter: base.WALLET_ADAPTERS.AUTH
}));
try {
await this.connectWithProvider(params);
return this.provider;
} catch (error) {
base.log.error("Failed to connect with auth provider", error);
// ready again to be connected
this.status = base.ADAPTER_STATUS.READY;
this.emit(base.ADAPTER_EVENTS.ERRORED, error);
if (error !== null && error !== void 0 && error.message.includes("user closed popup")) {
throw base.WalletLoginError.popupClosed();
} else if (error instanceof base.Web3AuthError) {
throw error;
}
throw base.WalletLoginError.connectionError("Failed to login with auth", error);
}
}
async enableMFA(params = {
loginProvider: ""
}) {
if (this.status !== base.ADAPTER_STATUS.CONNECTED) throw base.WalletLoginError.notConnectedError("Not connected with wallet");
if (!this.authInstance) throw base.WalletInitializationError.notReady("authInstance is not ready");
try {
await this.authInstance.enableMFA(params);
} catch (error) {
base.log.error("Failed to enable MFA with auth provider", error);
if (error instanceof base.Web3AuthError) {
throw error;
}
throw base.WalletLoginError.connectionError("Failed to enable MFA with auth", error);
}
}
async manageMFA(params = {
loginProvider: ""
}) {
if (this.status !== base.ADAPTER_STATUS.CONNECTED) throw base.WalletLoginError.notConnectedError("Not connected with wallet");
if (!this.authInstance) throw base.WalletInitializationError.notReady("authInstance is not ready");
try {
await this.authInstance.manageMFA(params);
} catch (error) {
base.log.error("Failed to manage MFA with auth provider", error);
if (error instanceof base.Web3AuthError) {
throw error;
}
throw base.WalletLoginError.connectionError("Failed to manage MFA with auth", error);
}
}
async disconnect(options = {
cleanup: false
}) {
if (this.status !== base.ADAPTER_STATUS.CONNECTED) throw base.WalletLoginError.notConnectedError("Not connected with wallet");
if (!this.authInstance) throw base.WalletInitializationError.notReady("authInstance is not ready");
await this.authInstance.logout();
if (options.cleanup) {
this.status = base.ADAPTER_STATUS.NOT_READY;
this.authInstance = null;
this.privateKeyProvider = null;
} else {
// ready to be connected again
this.status = base.ADAPTER_STATUS.READY;
}
this.rehydrated = false;
this.emit(base.ADAPTER_EVENTS.DISCONNECTED);
}
async authenticateUser() {
if (this.status !== base.ADAPTER_STATUS.CONNECTED) throw base.WalletLoginError.notConnectedError("Not connected with wallet, Please login/connect first");
const userInfo = await this.getUserInfo();
return {
idToken: userInfo.idToken
};
}
async getUserInfo() {
if (this.status !== base.ADAPTER_STATUS.CONNECTED) throw base.WalletLoginError.notConnectedError("Not connected with wallet");
if (!this.authInstance) throw base.WalletInitializationError.notReady("authInstance is not ready");
const userInfo = this.authInstance.getUserInfo();
return userInfo;
}
// should be called only before initialization.
setAdapterSettings(adapterSettings) {
super.setAdapterSettings(adapterSettings);
const defaultOptions = config.getAuthDefaultOptions();
base.log.info("setting adapter settings", adapterSettings);
this.authOptions = deepmerge.all([defaultOptions.adapterSettings, this.authOptions || {}, adapterSettings || {}]);
if (adapterSettings.web3AuthNetwork) {
this.authOptions.network = adapterSettings.web3AuthNetwork;
}
if (adapterSettings.privateKeyProvider) {
this.privateKeyProvider = adapterSettings.privateKeyProvider;
}
}
async addChain(chainConfig, init = false) {
var _this$privateKeyProvi;
super.checkAddChainRequirements(chainConfig, init);
(_this$privateKeyProvi = this.privateKeyProvider) === null || _this$privateKeyProvi === void 0 || _this$privateKeyProvi.addChain(chainConfig);
this.addChainConfig(chainConfig);
}
async switchChain(params, init = false) {
var _this$privateKeyProvi2;
super.checkSwitchChainRequirements(params, init);
await ((_this$privateKeyProvi2 = this.privateKeyProvider) === null || _this$privateKeyProvi2 === void 0 ? void 0 : _this$privateKeyProvi2.switchChain(params));
this.setAdapterSettings({
chainConfig: this.getChainConfig(params.chainId)
});
}
_getFinalPrivKey() {
if (!this.authInstance) return "";
let finalPrivKey = this.authInstance.privKey;
// coreKitKey is available only for custom verifiers by default
if (this.useCoreKitKey) {
// this is to check if the user has already logged in but coreKitKey is not available.
// when useCoreKitKey is set to true.
// This is to ensure that when there is no user session active, we don't throw an exception.
if (this.authInstance.privKey && !this.authInstance.coreKitKey) {
throw base.WalletLoginError.coreKitKeyNotFound();
}
finalPrivKey = this.authInstance.coreKitKey;
}
return finalPrivKey;
}
_getFinalEd25519PrivKey() {
if (!this.authInstance) return "";
let finalPrivKey = this.authInstance.ed25519PrivKey;
// coreKitKey is available only for custom verifiers by default
if (this.useCoreKitKey) {
// this is to check if the user has already logged in but coreKitKey is not available.
// when useCoreKitKey is set to true.
// This is to ensure that when there is no user session active, we don't throw an exception.
if (this.authInstance.ed25519PrivKey && !this.authInstance.coreKitEd25519Key) {
throw base.WalletLoginError.coreKitKeyNotFound();
}
finalPrivKey = this.authInstance.coreKitEd25519Key;
}
return finalPrivKey;
}
async connectWithProvider(params = {
loginProvider: ""
}) {
var _params$extraLoginOpt;
if (!this.privateKeyProvider) throw base.WalletInitializationError.invalidParams("PrivateKey Provider is required before initialization");
if (!this.authInstance) throw base.WalletInitializationError.notReady("authInstance is not ready");
const keyAvailable = this._getFinalPrivKey();
// if not logged in then login
if (!keyAvailable || (_params$extraLoginOpt = params.extraLoginOptions) !== null && _params$extraLoginOpt !== void 0 && _params$extraLoginOpt.id_token) {
var _params$extraLoginOpt2;
// always use "other" curve to return token with all keys encoded so wallet service can switch between evm and solana namespace
this.loginSettings.curve = auth.SUPPORTED_KEY_CURVES.OTHER;
if (!params.loginProvider && !this.loginSettings.loginProvider) throw base.WalletInitializationError.invalidParams("loginProvider is required for login");
await this.authInstance.login(deepmerge.all([this.loginSettings, params, {
extraLoginOptions: _objectSpread(_objectSpread({}, params.extraLoginOptions || {}), {}, {
login_hint: params.login_hint || ((_params$extraLoginOpt2 = params.extraLoginOptions) === null || _params$extraLoginOpt2 === void 0 ? void 0 : _params$extraLoginOpt2.login_hint)
})
}]));
}
let finalPrivKey = this._getFinalPrivKey();
if (finalPrivKey) {
if (this.currentChainNamespace === base.CHAIN_NAMESPACES.SOLANA) {
finalPrivKey = this._getFinalEd25519PrivKey();
}
await this.privateKeyProvider.setupProvider(finalPrivKey);
this.status = base.ADAPTER_STATUS.CONNECTED;
this.emit(base.ADAPTER_EVENTS.CONNECTED, {
adapter: base.WALLET_ADAPTERS.AUTH,
reconnected: this.rehydrated,
provider: this.provider
});
}
}
}
exports.AuthAdapter = AuthAdapter;