Authenticate with beforeLogin function and external API

Maybe it’s strange, or it can be done in another way. I tell you what I want.

I use web3Auth for users to login (using 2.0 and 3.0 methods), but I don’t want to return any data like ethAddress, username, etc. on the client when I use the Moralis.authenticate function, and I would like to get a token generated in a External API.

I use the Molaris user data to create a user in another DB with: objectId, ethAddress,and username. Once the user is created, I create the token and return it to the client.

I’ve come up with a solution that works, but it’s not pretty at all.
I have a function in the cloud (Moralis.Cloud.beforeLogin), and inside it I take the user data, and call another function (Moralis.Cloud.httpRequest) that calls the external API. This API returns the token to me in the cloud function.

Here comes the problem. If I return the token, it doesn’t reach the client, because the usual response from the Moralis.authenticate call arrives. So what I do is return an error in the cloud function, and I intercept it on the client (I had to modify the moralis.js library to be able to handle the response), and fudge to use the token and other data that I also return in the cloud function.

The cloud function:

Moralis.Cloud.beforeLogin(async (request, res) => {
  const { object: user } = request;
  const fileObject = await makerequest(user, res);
  return fileObject;
});

async function makerequest(user, res){
  let results = "";
  await Moralis.Cloud.httpRequest({
    method: 'POST',
    url: 'https://raito.care/api/signin',
    followRedirects: true,
    headers: {
      'Content-Type': 'application/json;charset=utf-8'
    },
    body: {"objectId":"************","ethAddress":"****************","username":"***************","lang":"en","email":""}
  })
    .then((res) => {
      results = res;
    })
    .catch((err) => {
      results = err;
    });
    var resp = JSON.parse(results.text)
    var dev = {code:results.text.status,error:resp};
    throw dev;
    //return results.text;
}

Client code:

authenticate(){
    return Moralis.authenticate({ provider: 'web3Auth', clientId: environment.moralisClientId, appLogo: 'https://raito.care/assets/img/logo-raito.png', theme: 'light' })
      .then( (user : any) => {
       }, (err) => {
         console.log(err);
         if(err.message=='You have successfully logged in'){
          return err;
         }else{
          this.logout();
         }
         
       })
  }

I am not posting the code that I have modified from moralis.js because it is already too long :smiley:

I am using [email protected]/dist/moralis.js and https://cdn.jsdelivr.net/npm/@web3auth/[email protected], and an Angular app.
Is there any simpler solution? Thanks in advance! :upside_down_face:

Moralis Auth API would be easier in this case. You can find an example with Web3Auth Here

From the cloud function, you could also query the user in the db and save the key there which you can grab from the client, but in this case, all the normal user data is going to reach the client too

Thank you very much for your answer. I don’t want the second option. I’m trying the first one, but it gives me errors when I install the libraries in my Angular project :frowning:

With wagmi the same thing happens to me, more errors in the compilation
I’ll keep trying, I don’t want to use next.js, since the project is finished in Angular.

Thanks

I have also tried with react, and another error appears that also appears in Angular:

What libraries did you install in your Angular project? Can you post your package.json?

You can ignore that type issue for now.

Yes, I can remove that issue, but not those of the Angular console, they do not allow the application to be launched due to errors of the @web3auth/web3auth-wagmi-connector librarie.

{
  "name": "Raito",
  "version": "2.0.0",
  "license": "",
  "scripts": {
    "ng": "ng",
    "start": "ng serve",
    "build": "ng build",
    "postinstall": "ngcc --properties es2015 browser module main --first-only --create-ivy-entry-points"
  },
  "private": true,
  "dependencies": {
    "@akveo/ng2-completer": "^9.0.1",
    "@angular-slider/ngx-slider": "^2.0.3",
    "@angular/animations": "9.0.1",
    "@angular/cdk": "^9.0.0",
    "@angular/common": "9.0.1",
    "@angular/compiler": "9.0.1",
    "@angular/core": "9.0.1",
    "@angular/forms": "9.0.1",
    "@angular/localize": "^9.0.1",
    "@angular/material": "^9.2.0",
    "@angular/platform-browser": "9.0.1",
    "@angular/platform-browser-dynamic": "9.0.1",
    "@angular/platform-server": "9.0.1",
    "@angular/router": "9.0.1",
    "@ng-bootstrap/ng-bootstrap": "5.3.0",
    "@ng-select/ng-select": "3.7.2",
    "@ngrx/store": "8.6.0",
    "@ngx-translate/core": "12.1.1",
    "@ngx-translate/http-loader": "4.0.0",
    "@swimlane/ngx-charts": "^13.0.2",
    "@swimlane/ngx-datatable": "^16.0.3",
    "@types/jquery": "^3.3.34",
    "@types/node": "^13.7.1",
    "@veriff/incontext-sdk": "^1.3.1",
    "@veriff/js-sdk": "^1.2.3",
    "@web3auth/web3auth-wagmi-connector": "^1.0.0",
    "angular-calendar": "^0.28.28",
    "angulartics2": "^8.3.0",
    "angularx-qrcode": "^2.3.7",
    "apexcharts": "^3.27.2",
    "bootstrap": "4.4.1",
    "calendar-utils": "0.0.59",
    "chartist": "^0.11.4",
    "chartist-plugin-tooltip": "0.0.11",
    "classlist.js": "1.1.20150312",
    "core-js": "3.6.4",
    "crypto-es": "^1.2.7",
    "d3": "^5.16.0",
    "d3-shape": "^1.3.7",
    "date-fns": "^2.16.1",
    "ethers": "^5.7.1",
    "faker": "^4.1.0",
    "file-saver": "^2.0.2",
    "gulp": "4.0.2",
    "highcharts": "^8.0.4",
    "install": "^0.13.0",
    "intl": "1.2.5",
    "jquery": "^3.5.0",
    "js-sha512": "^0.8.0",
    "jspdf": "^2.3.1",
    "jspdf-autotable": "^3.5.20",
    "jwt-decode": "^2.2.0",
    "karma-coverage": "^2.0.2",
    "marked": "^0.8.2",
    "moralis": "^1.8.0",
    "ng-apexcharts": "^1.5.12",
    "ng-chartist": "^4.1.0",
    "ng2-smart-table": "^1.6.0",
    "ngx-chips": "^2.1.0",
    "ngx-custom-validators": "^8.0.0",
    "ngx-hotjar": "^9.0.2",
    "ngx-perfect-scrollbar": "9.0.0",
    "ngx-toastr": "^12.0.0",
    "ngx-ui-switch": "^9.0.1",
    "node-sass": "4.13.1",
    "npm": "^6.14.4",
    "prismjs": "1.19.0",
    "resize-observer-polyfill": "1.5.1",
    "rxjs": "6.5.4",
    "screenfull": "5.0.2",
    "source-map-support": "^0.5.19",
    "sweetalert2": "^11.0.18",
    "tslib": "^1.10.0",
    "uuid": "^8.3.2",
    "venn.js": "^0.2.20",
    "wagmi": "^0.6.8",
    "web-animations-js": "^2.3.2",
    "zone.js": "~0.10.2"
  },
  "devDependencies": {
    "@angular-devkit/build-angular": "~0.900.2",
    "@angular/cli": "9.0.2",
    "@angular/compiler-cli": "9.0.1",
    "@angular/language-service": "9.0.1",
    "@types/d3": "^5.7.2",
    "@types/jasmine": "3.5.4",
    "codelyzer": "^5.1.2",
    "dotenv": "^8.2.0",
    "jasmine-core": "3.5.0",
    "jasmine-reporters": "^2.3.2",
    "jasmine-spec-reporter": "4.2.1",
    "karma": "4.4.1",
    "karma-chrome-launcher": "3.1.0",
    "karma-cli": "~2.0.0",
    "karma-coverage-istanbul-reporter": "2.1.1",
    "karma-jasmine": "3.1.1",
    "karma-jasmine-html-reporter": "1.5.2",
    "karma-junit-reporter": "^2.0.1",
    "protractor": "5.4.3",
    "protractor-console-plugin": "^0.1.1",
    "puppeteer": "^4.0.0",
    "rxjs-compat": "6.5.4",
    "ts-node": "8.6.2",
    "tslint": "6.0.0",
    "typescript": "3.7.5",
    "yargs": "^15.4.1"
  }
}

To test can you try using the web3auth connector package in a new Angular project.

How are you using the connector in your code?

Thanks, I’ll try it on a new project.

The code is public in this branch

Thanks again

I get errors trying to install that branch so am unable to test on my end. I don’t see @web3auth/web3auth-wagmi-connector in the package.json (or any web3auth library) - what is the actual library(s) when installed that leads to those errors?

Sorry Glad, I hadn’t seen your message. With Wagni I was doing tests in another branch.

I haven’t had time to test on a new project yet.
Thank you very much @alex :wink:

If you are able to create a reproducable example with a new project, then be sure to post. It looks ok but I still can’t install on my end.

I have been able to install the libraries without errors in an Angular project, but I don’t know how to make it work, since the tutorials are for NextJS. :upside_down_face:

I have tried, but I get an error in the connector, which did not appear in my project:

Thanks and regards!

What is the full code that that connector object is inside of and how have you imported the Web3AuthConnector? The popup is blocking it.


Also, the problem I see is that I don’t use WagmiCongif, as it does it as a wrap in NextJs, but in Angular I don’t know how to do it.
I don’t want to waste your time. If there is no example in Angular, maybe it is not possible.

You would need to use @wagmi/core in that case, which is the base library for wagmi (React).

It looks like the Web3Auth connector already uses it so it can possibly work directly. But you still would need a backend to use the Auth API similar to the Next.js tutorial linked above.

Thank you very much @alex !

I have tried but nothing. I’m going to quit, I’m spending too much time on this. Thanks a lot for everything

You’re still trying to use the hooks it looks like (any function starting with use) - you can only use these in React apps. You would need to use the base methods from @wagmi/core. E.g. if you wanted to connect your MetaMask or injected wallet, you would do something like:

import { createClient, connect, configureChains, chain } from '@wagmi/core';
import { InjectedConnector } from 'wagmi/connectors/injected';
import { publicProvider } from 'wagmi/providers/public';

// set up chains and provider
const { chains, provider } = configureChains([
  chain.mainnet,
  chain.polygon,
], [publicProvider()]);

// set up Wagmi client
const client = createClient({
    autoConnect: true,
    provider: provider
});

// connect function 
async function connectWallet() {
    await connect({connector: new InjectedConnector()});
}

Probably easier at this stage to stick with your existing method or work with the v1 Web3Auth connector as you’re using moralis-v1 / Moralis servers.

Oooooooooo :heart_eyes:

That changes everything! I had no idea the termination use is for react, and it doesn’t work for Angular. I have removed ‘use’.

I have had to change several things, like polyfills, and install several devDependencies like crypto-browserify, but it works now!

I have also had to change the parameters, because it has not worked for me with InjectedConnector, nor with other providers such as WalletConnector

Now it’s giving me another error, but at least I’ve made progress.

Happy day and thank you very much for your time!

If you upload a working repo of where you’ve gotten to with this, I can take a look.