Skip to content

Commit

Permalink
✨ feat: LOGIN WITH LINKCODE config.linkCode #3233
Browse files Browse the repository at this point in the history
  • Loading branch information
smashah committed Aug 7, 2024
1 parent 3ebc0f8 commit 4788ec4
Show file tree
Hide file tree
Showing 5 changed files with 93 additions and 6 deletions.
45 changes: 45 additions & 0 deletions docs/docs/get-started/link-code.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
---
title: Logging in with a link code
sidebar_label: Link Code Login
sidebar_position: 3
description:
Simple docs showing how to use open-wa/wa-automate with a link code.
---

# Intro

For many years the standard way to login to your host account was to scan a QR code. However, recently link code has been introduced as an option. This guide will show you how to use the link code to login to your host account.

The main thing to know is that you will need to know exactly which host account number you're using before starting the session. This is because the link code is specific to the host account number.

Once the link code is requested from the session, the host account device will be sent a notification to confirm the login. Once confirmed, the host account device will ask you to enter the link code.

The link code is a 8 character string that is displayed on the screen of the host account device with a `-` in between, for example: `1EV4-5A78`.

In open-wa, the way to activate the link code request is to set the host account number as a string or number beforehand as a property of the config object in the `linkCode` property.

## Easy API

If you're using the Easy API, you can set the link code in the config object like so:

```bash
> npx @open-wa/wa-automate --linkCode '447123456789'
```

Or if you're using the `cli.config.json` file:

```json
{
"linkCode": "1234567890"
}
```

## In code

You can also set the link code manually in the code like so:

```javascript
create({
linkCode: '1234567890'
})
```
9 changes: 9 additions & 0 deletions src/api/model/config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -245,6 +245,15 @@ export interface ConfigObject {
* Setting the sessionData in the environmental variable will override the sessionData object in the config.
*/
sessionData?: SessionData | Base64,
/**
* There is a new way to login to your host account by entering a link code after a confirmation step from the host account device. In order to use this feature you MUST set the host account number as a string or number beforehand as a property of the config object.
*
* e.g
* ```
* linkCode: '1234567890'
* ```
*/
linkCode?: string;
/**
* ALPHA EXPERIMENTAL FEATURE! DO NOT USE IN PRODUCTION, REQUIRES TESTING.
*
Expand Down
39 changes: 35 additions & 4 deletions src/controllers/auth.ts
Original file line number Diff line number Diff line change
Expand Up @@ -129,6 +129,7 @@ export class QRManager {
}

async grabAndEmit(qrData, waPage: Page, config: ConfigObject, spinner: Spin) {
const isLinkCode = qrData.length === 9
this.qrNum++;
if (config.qrMax && this.qrNum > config.qrMax) {
spinner.info('QR Code limit reached, exiting...');
Expand All @@ -139,9 +140,13 @@ export class QRManager {
if (qrData) {
qrEv.emit(qrData, `qrData`);
if (!config.qrLogSkip) {
qrcode.generate(qrData, { small: true }, terminalQrCode => {
console.log(boxen(terminalQrCode, {title: config.sessionId, padding: 1, titleAlignment: 'center'}));
});
if(isLinkCode) {
console.log(boxen(qrData, {title: `ENTER THIS CODE ON THE HOST ACCOUNT DEVICE: ${config.sessionId}`, padding: 1, titleAlignment: 'center'}));
} else {
qrcode.generate(qrData, { small: true }, terminalQrCode => {
console.log(boxen(terminalQrCode, {title: config.sessionId, padding: 1, titleAlignment: 'center'}));
});
}
}
else {
console.log(`New QR Code generated. Not printing in console because qrLogSkip is set to true`)
Expand All @@ -155,7 +160,7 @@ export class QRManager {
this._internalQrPngLoaded = true;
}
try {
const qrPng = await waPage.evaluate(`window.getQrPng()`);
const qrPng = isLinkCode ? qrData : await waPage.evaluate(`window.getQrPng()`);
if (qrPng) {
qrEv.emit(qrPng);
processSend('ready');
Expand Down Expand Up @@ -189,6 +194,29 @@ export class QRManager {
}
}

async linkCode(waPage: Page, config?: ConfigObject, spinner?: Spin): Promise<boolean | void | string> {
const evalResult = await waPage.evaluate("window.Store && window.Store.State")
if (evalResult === false) {
console.log('Seems as though you have been TOS_BLOCKed, unable to refresh QR Code. Please see https://github.com/open-wa/wa-automate-nodejs#best-practice for information on how to prevent this from happeing. You will most likely not get a QR Code');
log.warn('Seems as though you have been TOS_BLOCKed, unable to refresh QR Code. Please see https://github.com/open-wa/wa-automate-nodejs#best-practice for information on how to prevent this from happeing. You will most likely not get a QR Code');
if (config.throwErrorOnTosBlock) throw new Error('TOSBLOCK');
}

const isAuthed = await isAuthenticated(waPage);
if (isAuthed) return true;

const _hasDefaultStateYet = await waPage.evaluate("!!(window.Store && window.Store.State && window.Store.State.Socket)")
if (!_hasDefaultStateYet) {
//expecting issue, take a screenshot then wait a few seconds before continuing
await timeout(2000);
}
spinner.info('Link Code requested, please use the link code to login from your host account device')
const linkCode = await waPage.evaluate((number)=> window['linkCode'](number), config?.linkCode)
spinner?.succeed(`Link Code please use this to login from your host account device: ${linkCode}`)
await this.grabAndEmit(linkCode, waPage, config, spinner)
return await isInsideChat(waPage).toPromise()
}

async smartQr(waPage: Page, config?: ConfigObject, spinner?: Spin): Promise<boolean | void | string> {
const evalResult = await waPage.evaluate("window.Store && window.Store.State")
if (evalResult === false) {
Expand Down Expand Up @@ -250,6 +278,9 @@ export class QRManager {
* If it doesn't show up within 10 seconds then assume the session is authed already or blocked therefore ignore and return promise
*/
async waitFirstQr(waPage: Page, config?: ConfigObject, spinner?: Spin){
/**
* Check if session is authed already
*/
const fqr = await waPage.waitForFunction(`!!(${this.qrCheck})`, {
polling: 500,
timeout: 10000
Expand Down
4 changes: 3 additions & 1 deletion src/controllers/initializer.ts
Original file line number Diff line number Diff line change
Expand Up @@ -271,7 +271,9 @@ export async function create(config: AdvancedConfig | ConfigObject = {}): Promis
} else {
spinner.info('Authenticate to continue');
const race = [];
race.push(qrManager.smartQr(waPage, config, spinner))
if(config?.linkCode) {
race.push(qrManager.linkCode(waPage, config, spinner))
} else race.push(qrManager.smartQr(waPage, config, spinner))
if (config?.qrTimeout!==0) {
let to = (config?.qrTimeout || 60) * 1000
if(config?.multiDevice) to = to * 2
Expand Down
2 changes: 1 addition & 1 deletion src/lib/launch.js

Large diffs are not rendered by default.

0 comments on commit 4788ec4

Please sign in to comment.