Skip to content

Commit 5ff7831

Browse files
authored
Merge pull request #6 from code-yeongyu/naver-2fa
사용자는 `rxjs` subscription 을 활용해 네이버 2중 인증으로도 로그인 할 수 있습니다.
2 parents c2e0fe0 + da1bd3e commit 5ff7831

File tree

12 files changed

+729
-30
lines changed

12 files changed

+729
-30
lines changed

.vscode/settings.json

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
{
2+
"editor.tabSize": 2
3+
}

codecov.yml

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
coverage:
2+
status:
3+
project: no
4+
patch: no

example/naver/printPaymentHistory.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,7 @@ const printNaverPayHistory = async (id: string, password: string) => {
1818
const module = NaverApp.ModuleFactory.create(page);
1919
const crawlService = new NaverApp.Service(module);
2020

21-
await crawlService.login(id, password);
21+
await crawlService.normalLogin(id, password);
2222

2323
const history = await crawlService.getHistory();
2424
console.log(history);
Lines changed: 56 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,56 @@
1+
import puppeteer from "puppeteer";
2+
import { NaverApp } from "trackpurchase";
3+
4+
import readline from "readline";
5+
import { concat, defer, filter, from, tap } from "rxjs";
6+
7+
const printNaverPayHistory = async (id: string, password: string) => {
8+
const MOBILE_UA =
9+
"Mozilla/5.0 (iPhone; CPU iPhone OS 15_1_1 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/15.1 Mobile/15E148 Safari/604.1";
10+
11+
const browser = await puppeteer.launch({
12+
headless: false,
13+
args: ["--start-maximized"],
14+
});
15+
16+
const page = await browser.newPage();
17+
await page.setViewport({ height: 800, width: 1200 });
18+
await page.setUserAgent(MOBILE_UA);
19+
20+
const module = NaverApp.ModuleFactory.create(page);
21+
const crawlService = new NaverApp.Service(module);
22+
23+
const loginEvent$ = crawlService.interactiveLogin(id, password);
24+
const history$ = defer(() => from(crawlService.getHistory()));
25+
const closePage$ = defer(() => from(page.close()));
26+
const closeBrowser$ = defer(() => from(browser.close()));
27+
28+
const final$ = concat(loginEvent$, history$, closePage$, closeBrowser$).pipe(
29+
tap((event) => {
30+
if (event === "otp-required") {
31+
console.log("스마트폰 앱에서 OTP 인증을 완료해주세요.");
32+
}
33+
}),
34+
tap((event) => {
35+
if (event === "manual-otp-required") {
36+
rl.question("otp code: ", async (code) => {
37+
module.pageInteractor.fillManualOTPInput(code);
38+
});
39+
}
40+
}),
41+
filter((event) => event instanceof Array)
42+
);
43+
final$.subscribe((event) => {
44+
console.log(event);
45+
});
46+
};
47+
48+
const rl = readline.createInterface({
49+
input: process.stdin,
50+
output: process.stdout,
51+
});
52+
rl.question("Naver ID: ", (id) => {
53+
rl.question("Naver Password: ", (password) => {
54+
printNaverPayHistory(id, password);
55+
});
56+
});

package.json

Lines changed: 8 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"name": "trackpurchase",
3-
"version": "0.1.14",
3+
"version": "1.0.0",
44
"main": "dist/index.js",
55
"license": "MIT",
66
"repository": {
@@ -21,7 +21,11 @@
2121
"preset": "jest-puppeteer",
2222
"coveragePathIgnorePatterns": [
2323
"dist/",
24-
"elementParser.ts"
24+
"elementParser.ts",
25+
"pageInteractor.ts"
26+
],
27+
"testPathIgnorePatterns": [
28+
"dist/"
2529
]
2630
},
2731
"scripts": {
@@ -30,7 +34,8 @@
3034
"build": "tsc -p ."
3135
},
3236
"dependencies": {
33-
"puppeteer": "^12.0.1"
37+
"puppeteer": "^12.0.1",
38+
"rxjs": "^7.5.2"
3439
},
3540
"devDependencies": {
3641
"@babel/core": "^7.16.5",

src/app/naver/elementParser.ts

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -114,4 +114,8 @@ export default class ElementParser {
114114
};
115115
return paymentHistory;
116116
}
117+
118+
async parseManualOTPInputElement() {
119+
return await this.page.$("#otp");
120+
}
117121
}

src/app/naver/index.ts

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
import Module from "./module";
22
import ModuleFactory from "./moduleFactory";
33
import URLChanger from "./urlChanger";
4-
import PageInteractor from "./pageInteractor";
4+
import PageInteractor, { LoginEvent } from "./pageInteractor";
55
import ElementParser from "./elementParser";
66
import Service from "./service";
77

@@ -12,4 +12,5 @@ export {
1212
PageInteractor,
1313
ElementParser,
1414
Service,
15+
LoginEvent,
1516
};

src/app/naver/moduleFactory.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,9 +3,9 @@ import { Module, URLChanger, ElementParser, PageInteractor } from ".";
33

44
export default class ModuleFactory {
55
static create(page: puppeteer.Page): Module {
6-
const pageInteractor = new PageInteractor(page);
76
const urlChanger = new URLChanger(page);
87
const elementParser = new ElementParser(page);
8+
const pageInteractor = new PageInteractor(page, elementParser);
99

1010
return {
1111
urlChanger,

0 commit comments

Comments
 (0)