-
Notifications
You must be signed in to change notification settings - Fork 1
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
feat(the-camp): the camp service login 기능 구현
- Loading branch information
Showing
17 changed files
with
231 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,4 @@ | ||
export interface Cookie { | ||
key: string; | ||
value: string; | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,3 @@ | ||
export * from './cookie'; | ||
export * from './parameter'; | ||
export * from './session'; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,16 @@ | ||
export class Parameter { | ||
constructor( | ||
private readonly data: Record<string, string | number | boolean>, | ||
) {} | ||
|
||
toString() { | ||
const rows: string[] = []; | ||
for (const key in this.data) { | ||
rows.push( | ||
`${encodeURIComponent(key)}=${encodeURIComponent(this.data[key])}`, | ||
); | ||
} | ||
|
||
return rows.join('&'); | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,5 @@ | ||
import { Cookie } from './cookie'; | ||
|
||
export interface Session { | ||
cookies: Cookie[]; | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,4 @@ | ||
export interface Credential { | ||
id: string; | ||
password: string; | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1 @@ | ||
export * from './credential'; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1 @@ | ||
export * from './the-camp.service'; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1 @@ | ||
export * from './login'; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1 @@ | ||
export * from './login.requester'; |
13 changes: 13 additions & 0 deletions
13
src/services/the-camp/requesters/login/login.requester.e2e.spec.ts
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,13 @@ | ||
import { LoginRequester } from './login.requester'; | ||
|
||
describe.skip('LoginRequester e2e', () => { | ||
it('성공', async () => { | ||
const loginRequester = new LoginRequester(); | ||
|
||
const session = await loginRequester.request({ | ||
id: '', | ||
password: '', | ||
}); | ||
console.log('session', session); | ||
}); | ||
}); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,65 @@ | ||
import { Parameter, Session } from '@core/http'; | ||
import { Credential } from '@core/types'; | ||
import axios, { AxiosRequestConfig } from 'axios'; | ||
|
||
import { parseLogin } from './parse-login'; | ||
|
||
export class LoginRequester { | ||
constructor(private readonly parse = parseLogin) {} | ||
|
||
async request(credential: Credential): Promise<Session> { | ||
const response = await axios.post( | ||
'https://www.thecamp.or.kr/login/loginA.do', | ||
this.createPayload(credential), | ||
this.createOptions(), | ||
); | ||
return this.parse(response); | ||
} | ||
|
||
private createPayload(credential: Credential) { | ||
return new Parameter({ | ||
userId: credential.id, | ||
userPwd: credential.password, | ||
state: 'email-login', | ||
autoLoginYn: 'Y', | ||
withdrawDate: '', | ||
withdrawReason: '', | ||
reCertYn: '', | ||
telecomCd: '', | ||
telecomNm: '', | ||
osType: '', | ||
osVersion: '', | ||
deviceModel: '', | ||
appVersion: '', | ||
deviceWidth: '', | ||
deviceHeight: '', | ||
resultCd: '', | ||
resultMsg: '', | ||
findPwType: 'pwFind', | ||
}).toString(); | ||
} | ||
|
||
private createOptions(): AxiosRequestConfig { | ||
return { | ||
headers: { | ||
Accept: 'application/json, text/javascript, */*; q=0.01', | ||
'Accept-Encoding': 'gzip, deflate, br', | ||
'Accept-Language': 'ko-KR,ko;q=0.9,en-US;q=0.8,en;q=0.7', | ||
'Content-Type': 'application/x-www-form-urlencoded; charset=UTF-8', | ||
'User-Agent': | ||
'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/98.0.4758.70 Whale/3.13.131.27 Safari/537.36', | ||
Host: 'www.thecamp.or.kr', | ||
Origin: 'https://www.thecamp.or.kr', | ||
Referer: 'https://www.thecamp.or.kr/login/viewLogin.do', | ||
'X-Requested-With': 'XMLHttpRequest', | ||
'sec-ch-ua': '" Not A;Brand";v="99", "Chromium";v="98", "Whale";v="3"', | ||
'sec-ch-ua-mobile': '?0', | ||
'sec-ch-ua-platform': '"macOS"', | ||
'Sec-Fetch-Site': 'same-origin', | ||
'Sec-Fetch-Mode': 'cors', | ||
'Sec-Fetch-Dest': 'empty', | ||
}, | ||
}; | ||
} | ||
} | ||
export const loginRequester = new LoginRequester(); |
37 changes: 37 additions & 0 deletions
37
src/services/the-camp/requesters/login/parse-login.spec.ts
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,37 @@ | ||
import { parseLogin } from './parse-login'; | ||
import 성공 from './test/성공.json'; | ||
import 실패_credentail from './test/실패-credentail.json'; | ||
import 실패_가입회원아님 from './test/실패-가입회원아님.json'; | ||
|
||
describe('parseLogin', () => { | ||
it('성공', () => { | ||
const cookies = parseLogin(성공 as any); | ||
|
||
expect(cookies).toEqual([ | ||
{ key: 'userId', value: 'paul2314%40naver.com' }, | ||
{ key: 'Token', value: 'sUl%2B4ShTmCqsX%2BXtf7X8MQ%3D%3D' }, | ||
{ key: 'iuid', value: '5302760' }, | ||
{ | ||
key: 'nickname', | ||
value: '%EC%A0%95%EC%9B%90%EB%B0%B0_%28%EC%9D%BC%EB%B0%98%29', | ||
}, | ||
{ key: 'name', value: '%EC%A0%95%EC%9B%90%EB%B0%B0' }, | ||
{ key: 'memberGradeCd', value: '0000340003' }, | ||
{ key: 'userId', value: 'paul2314%40naver.com' }, | ||
{ key: 'checkAutoLogin', value: 'off' }, | ||
{ key: 'checkSaveId', value: 'off' }, | ||
]); | ||
}); | ||
|
||
it('실패_credentail', () => { | ||
expect(() => parseLogin(실패_credentail as any)).toThrow( | ||
'이메일 또는 비밀번호가 맞지 않습니다.', | ||
); | ||
}); | ||
|
||
it('실패_가입회원아님', () => { | ||
expect(() => parseLogin(실패_가입회원아님 as any)).toThrow( | ||
'가입된 계정이 아닙니다. 회원가입 후 이용해주세요.', | ||
); | ||
}); | ||
}); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,34 @@ | ||
import { Cookie, Session } from '@core/http'; | ||
import { AxiosResponse } from 'axios'; | ||
|
||
export function parseLogin(response: AxiosResponse): Session { | ||
assertsResponse(response); | ||
|
||
const cookies: Cookie[] = []; | ||
const setCookie = response.headers['set-cookie']; | ||
// TODO: asserts | ||
|
||
if (!setCookie?.length) { | ||
throw new Error(''); | ||
} | ||
|
||
for (const cookie of setCookie) { | ||
const [key, value] = cookie.split(';')[0].split('='); | ||
cookies.push({ key, value }); | ||
} | ||
|
||
return { cookies }; | ||
} | ||
|
||
function assertsResponse(response: any) { | ||
if (response.data.resultCd === '9000') | ||
throw new Error('가입된 계정이 아닙니다. 회원가입 후 이용해주세요.'); | ||
|
||
if (response.data.resultCd === '9001') | ||
throw new Error('이메일 또는 비밀번호가 맞지 않습니다.'); | ||
|
||
if (response.data.resultCd !== '0000') | ||
throw new Error( | ||
response.data?.resultMsg || '알 수 없는 오류가 발생하였습니다', | ||
); | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,22 @@ | ||
{ | ||
"headers": { | ||
"set-cookie": [ | ||
"userId=paul2314%40naver.com; Max-Age=604800; Expires=Tue, 08-Mar-2022 11:48:42 GMT; Path=/", | ||
"Token=sUl%2B4ShTmCqsX%2BXtf7X8MQ%3D%3D; Max-Age=604800; Expires=Tue, 08-Mar-2022 11:48:42 GMT; Path=/", | ||
"iuid=5302760; Max-Age=604800; Expires=Tue, 08-Mar-2022 11:48:42 GMT; Path=/", | ||
"nickname=%EC%A0%95%EC%9B%90%EB%B0%B0_%28%EC%9D%BC%EB%B0%98%29; Max-Age=604800; Expires=Tue, 08-Mar-2022 11:48:42 GMT; Path=/", | ||
"name=%EC%A0%95%EC%9B%90%EB%B0%B0; Max-Age=604800; Expires=Tue, 08-Mar-2022 11:48:42 GMT; Path=/", | ||
"memberGradeCd=0000340003; Max-Age=604800; Expires=Tue, 08-Mar-2022 11:48:42 GMT; Path=/", | ||
"userId=paul2314%40naver.com; Max-Age=2592000; Expires=Thu, 31-Mar-2022 11:48:42 GMT; Path=/", | ||
"checkAutoLogin=off; Max-Age=2592000; Expires=Thu, 31-Mar-2022 11:48:42 GMT; Path=/", | ||
"checkSaveId=off; Max-Age=2592000; Expires=Thu, 31-Mar-2022 11:48:42 GMT; Path=/" | ||
] | ||
}, | ||
"data": { | ||
"resultCd": "0000", | ||
"resultMsg": "정상처리되었습니다.", | ||
"reCertYn": "Y", | ||
"iuid": "5302760", | ||
"newCheck": false | ||
} | ||
} |
6 changes: 6 additions & 0 deletions
6
src/services/the-camp/requesters/login/test/실패-credentail.json
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,6 @@ | ||
{ | ||
"data": { | ||
"resultCd": "9001", | ||
"resultMsg": "이메일 또는 비밀번호가 맞지 않습니다. 다시 확인하여 입력해 주세요." | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,6 @@ | ||
{ | ||
"data": { | ||
"resultCd": "9000", | ||
"resultMsg": "캠프 가입회원이 아닙니다. 회원가입 후 이용해 주세요." | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,12 @@ | ||
import { Session } from '@core/http'; | ||
import { Credential } from '@core/types'; | ||
|
||
import { loginRequester as _loginRequester } from './requesters'; | ||
|
||
export class TheCampService { | ||
constructor(private readonly loginRequester = _loginRequester) {} | ||
|
||
async login(credential: Credential): Promise<Session> { | ||
return await this.loginRequester.request(credential); | ||
} | ||
} |