Skip to content

Commit

Permalink
Merge pull request #2 from SEOKKAMONI/main
Browse files Browse the repository at this point in the history
ADD: 졸업생 구분 추가
  • Loading branch information
leehj050211 authored Nov 6, 2023
2 parents a0eb7a6 + 5852e37 commit 8e5a34a
Show file tree
Hide file tree
Showing 13 changed files with 120 additions and 75 deletions.
10 changes: 10 additions & 0 deletions .prettierrc
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
{
"singleQuote": true,
"semi": true,
"useTabs": false,
"tabWidth": 2,
"trailingComma": "none",
"printWidth": 120,
"arrowParens": "avoid",
"bracketSameLine": false
}
25 changes: 23 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,16 +1,25 @@
# BSM OAuth JS

[BSM Auth](https://github.com/BSSM-BSM/BSM-Auth-Backend-V1)의 OAuth기능을 JS에서 사용하기 쉽게 만들어주는 라이브러리입니다.

## 설치

```bash
$ npm install bsm-oauth
```

## 사용하기

### TypeScript

```typescript
import BsmOauth, { BsmOauthError, BsmOauthErrorType, BsmUserRole, BsmStudentResource, BsmTeacherResource } from "bsm-oauth";
import BsmOauth, {
BsmOauthError,
BsmOauthErrorType,
BsmUserRole,
BsmStudentResource,
BsmTeacherResource
} from 'bsm-oauth';

// BSM OAuth 객체 초기화
const bsmOauth = new BsmOauth(BSM_AUTH_CLIENT_ID, BSM_AUTH_CLIENT_SECRET);
Expand Down Expand Up @@ -38,9 +47,18 @@ try {
}
}
```

### JavaScript

```typescript
const { BsmOauth, BsmOauthError, BsmOauthErrorType, BsmUserRole, BsmStudentResource, BsmTeacherResource } = require('bsm-oauth');
const {
BsmOauth,
BsmOauthError,
BsmOauthErrorType,
BsmUserRole,
BsmStudentResource,
BsmTeacherResource
} = require('bsm-oauth');

const bsmOauth = new BsmOauth(BSM_AUTH_CLIENT_ID, BSM_AUTH_CLIENT_SECRET);

Expand Down Expand Up @@ -69,8 +87,11 @@ const bsmOauth = new BsmOauth(BSM_AUTH_CLIENT_ID, BSM_AUTH_CLIENT_SECRET);
}
})();
```

### 학생, 선생님계정 구분하기

role 속성으로 구분할 수 있습니다.

```javascript
// TypeScript에서는 role로 타입을 추론해야 학생 및 선생님 정보에 접근 가능합니다.
if (resource.role === BsmUserRole.STUDENT) {
Expand Down
9 changes: 1 addition & 8 deletions index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,11 +6,4 @@ import { BsmStudentResource } from './lib/types/student.js';
import { BsmTeacherResource } from './lib/types/teacher.js';

export default BsmOauth;
export {
BsmOauth,
BsmOauthError,
BsmOauthErrorType,
BsmUserRole,
BsmStudentResource,
BsmTeacherResource
}
export { BsmOauth, BsmOauthError, BsmOauthErrorType, BsmUserRole, BsmStudentResource, BsmTeacherResource };
83 changes: 39 additions & 44 deletions lib/bsmOauth.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import axios, { AxiosError } from 'axios';
import axios, { isAxiosError } from 'axios';
import BsmOauthError from './error.js';
import ErrorType from './types/errorType.js';
import { RawBsmOAuthResource, RawBsmOAuthToken } from './types/rawOAuthType.js';
Expand All @@ -7,7 +7,6 @@ import { BsmTeacher, BsmTeacherResource } from './types/teacher.js';
import UserRole from './types/userRole.js';

export default class BsmOauth {

constructor(clientId: string, clientSecret: string) {
this.bsmAuthPayload = {
clientId,
Expand All @@ -16,24 +15,29 @@ export default class BsmOauth {
}

private bsmAuthPayload: {
clientId: string,
clientSecret: string
clientId: string;
clientSecret: string;
};
private readonly BSM_AUTH_TOKEN_URL: string = "https://auth.bssm.kro.kr/api/oauth/token";
private readonly BSM_AUTH_RESOURCE_URL: string = "https://auth.bssm.kro.kr/api/oauth/resource";
private readonly BSM_AUTH_TOKEN_URL: string = 'https://auth.bssm.kro.kr/api/oauth/token';
private readonly BSM_AUTH_RESOURCE_URL: string = 'https://auth.bssm.kro.kr/api/oauth/resource';

public async getToken(authCode: string): Promise<string> {
try {
return (await axios.post<RawBsmOAuthToken>(this.BSM_AUTH_TOKEN_URL, {
...this.bsmAuthPayload,
authCode
})).data.token;
return (
await axios.post<RawBsmOAuthToken>(this.BSM_AUTH_TOKEN_URL, {
...this.bsmAuthPayload,
authCode
})
).data.token;
} catch (error) {
if (error instanceof AxiosError) {
if (isAxiosError(error)) {
switch (error.response?.status) {
case 400: throw new BsmOauthError(ErrorType.INVALID_CLIENT, 'BSM OAuth 클라이언트 정보가 잘못되었습니다');
case 404: throw new BsmOauthError(ErrorType.AUTH_CODE_NOT_FOUND, 'BSM OAuth 인증 코드를 찾을 수 없습니다');
default: throw error;
case 400:
throw new BsmOauthError(ErrorType.INVALID_CLIENT, 'BSM OAuth 클라이언트 정보가 잘못되었습니다');
case 404:
throw new BsmOauthError(ErrorType.AUTH_CODE_NOT_FOUND, 'BSM OAuth 인증 코드를 찾을 수 없습니다');
default:
throw error;
}
}
throw error;
Expand All @@ -42,17 +46,22 @@ export default class BsmOauth {

public async getResource(token: string): Promise<BsmStudentResource | BsmTeacherResource> {
try {
const resource = (await axios.post<{ user: RawBsmOAuthResource }>(this.BSM_AUTH_RESOURCE_URL, {
...this.bsmAuthPayload,
token
})).data.user;
const resource = (
await axios.post<{ user: RawBsmOAuthResource }>(this.BSM_AUTH_RESOURCE_URL, {
...this.bsmAuthPayload,
token
})
).data.user;
return this.toResource(resource);
} catch (error) {
if (error instanceof AxiosError) {
if (isAxiosError(error)) {
switch (error.response?.status) {
case 400: throw new BsmOauthError(ErrorType.INVALID_CLIENT, 'BSM OAuth 클라이언트 정보가 잘못되었습니다');
case 404: throw new BsmOauthError(ErrorType.TOKEN_NOT_FOUND, 'BSM OAuth 토큰을 찾을 수 없습니다');
default: throw error;
case 400:
throw new BsmOauthError(ErrorType.INVALID_CLIENT, 'BSM OAuth 클라이언트 정보가 잘못되었습니다');
case 404:
throw new BsmOauthError(ErrorType.TOKEN_NOT_FOUND, 'BSM OAuth 토큰을 찾을 수 없습니다');
default:
throw error;
}
}
throw error;
Expand All @@ -61,48 +70,34 @@ export default class BsmOauth {

private toResource(resource: RawBsmOAuthResource): BsmStudentResource | BsmTeacherResource {
const { code: userCode, role, nickname, email, profileUrl } = resource;
const commonResource = {
userCode,
nickname,
email,
profileUrl
};
const commonResource = { userCode, nickname, email, profileUrl };

if (role === UserRole.STUDENT) {
return {
...commonResource,
role,
student: this.toStudent(resource)
}
return { ...commonResource, role, student: this.toStudent(resource) };
}
if (role === UserRole.TEACHER) {
return {
...commonResource,
role,
teacher: this.toTeacher(resource)
}
return { ...commonResource, role, teacher: this.toTeacher(resource) };
}
throw new BsmOauthError(ErrorType.INVALID_USER_ROLE);
}

private toStudent(resource: RawBsmOAuthResource): BsmStudent {
const { name, enrolledAt, grade, classNo, studentNo } = resource;
const isGraduate = !grade && !classNo && !studentNo;

return {
name,
enrolledAt,
grade,
classNo,
studentNo
studentNo,
isGraduate
};
}

private toTeacher(resource: RawBsmOAuthResource): BsmTeacher {
const { name } = resource;

return {
name
}
return { name };
}

}
}
13 changes: 5 additions & 8 deletions lib/error.ts
Original file line number Diff line number Diff line change
@@ -1,14 +1,11 @@
import ErrorType from "./types/errorType.js";
import ErrorType from './types/errorType.js';

export default class BsmOauthError extends Error {
constructor(
type: ErrorType,
message?: string
) {
super(message)
constructor(type: ErrorType, message?: string) {
super(message);
this.name = 'BsmOauthError';
this.type = type;
};
}

type: ErrorType;
}
}
6 changes: 3 additions & 3 deletions lib/types/commonResource.ts
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
import UserRole from "./userRole.js";
import UserRole from './userRole.js';

export default interface BsmOauthCommonResource {
readonly userCode: number;
readonly role: UserRole
readonly role: UserRole;
readonly nickname: string;
readonly email: string;
readonly profileUrl: string;
}
}
2 changes: 1 addition & 1 deletion lib/types/errorType.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,4 +5,4 @@ enum BsmOauthErrorType {
INVALID_USER_ROLE = 'INVALID_USER_ROLE'
}

export default BsmOauthErrorType;
export default BsmOauthErrorType;
4 changes: 2 additions & 2 deletions lib/types/rawOAuthType.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import UserRole from "./userRole.js";
import UserRole from './userRole.js';

export interface RawBsmOAuthToken {
readonly token: string;
Expand All @@ -15,4 +15,4 @@ export interface RawBsmOAuthResource {
readonly email: string;
readonly role: UserRole;
readonly profileUrl: string;
}
}
7 changes: 4 additions & 3 deletions lib/types/student.ts
Original file line number Diff line number Diff line change
@@ -1,15 +1,16 @@
import CommonResource from "./commonResource.js";
import UserRole from "./userRole.js";
import CommonResource from './commonResource.js';
import UserRole from './userRole.js';

export interface BsmStudent {
readonly name: string;
readonly enrolledAt: number;
readonly grade: number;
readonly classNo: number;
readonly studentNo: number;
readonly isGraduate: boolean;
}

export interface BsmStudentResource extends CommonResource {
readonly role: UserRole.STUDENT;
readonly student: BsmStudent;
}
}
4 changes: 2 additions & 2 deletions lib/types/teacher.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import CommonResource from "./commonResource.js";
import UserRole from "./userRole.js";
import CommonResource from './commonResource.js';
import UserRole from './userRole.js';

export interface BsmTeacher {
readonly name: string;
Expand Down
2 changes: 1 addition & 1 deletion lib/types/userRole.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,4 +3,4 @@ enum BsmUserRole {
TEACHER = 'TEACHER'
}

export default BsmUserRole;
export default BsmUserRole;
24 changes: 24 additions & 0 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

6 changes: 5 additions & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,8 @@
"scripts": {
"build": "npm run build:cjs & npm run build:esm",
"build:cjs": "tsc --p ./cjs/tsconfig.json",
"build:esm": "tsc --p ./esm/tsconfig.json"
"build:esm": "tsc --p ./esm/tsconfig.json",
"format": "prettier --write \"**/*.{ts,js,md}\""
},
"repository": {
"type": "git",
Expand All @@ -28,5 +29,8 @@
"dependencies": {
"axios": "^1.1.3",
"typescript": "^4.8.4"
},
"devDependencies": {
"prettier": "3.0.3"
}
}

0 comments on commit 8e5a34a

Please sign in to comment.