summaryrefslogtreecommitdiff
path: root/lib/nonsap/README.md
blob: 4b595e0032c24408b48d574946b9217476e8051d (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
# NONSAP Server Action 권한 관리 가이드

이 디렉토리는 NONSAP 시스템의 권한 인증 및 Server Action 보안을 위한 유틸리티를 포함하고 있습니다.

## 핵심 유틸리티: `withNonsapAuth`

`withNonsapAuth`는 Server Action을 생성할 때 사용하는 고차 함수(Higher-Order Function)입니다.  
반복적인 세션 체크, 권한 검증, 에러 핸들링 코드를 제거하고 비즈니스 로직에 집중할 수 있게 해줍니다.

### 파일 위치
- `lib/nonsap/action-utils.ts`

### 주요 기능
1. **세션 검증**: 사용자가 로그인되어 있는지 확인합니다.
2. **권한 검증**: `verifyNonsapPermission`을 사용하여 현재 페이지(URL)에서 해당 동작(Action)을 수행할 권한이 있는지 확인합니다.
3. **User ID 주입**: 검증된 사용자 ID를 액션 함수의 두 번째 인자로 전달합니다.
4. **에러 핸들링**: 예기치 않은 에러를 포착하여 일관된 포맷으로 반환합니다.

---

## 사용 방법

### 1. Server Action 정의하기

기존의 Server Action 함수를 `withNonsapAuth`로 감싸서 내보냅니다.

```typescript
// lib/example/service.ts
'use server'

import { withNonsapAuth } from "@/lib/nonsap/action-utils";

// Input 타입 정의
interface CreateItemInput {
  name: string;
  price: number;
}

// withNonsapAuth 사용
// 첫 번째 인자: 필요한 권한 목록 (예: ['ADD'], ['SAVE'], ['DEL'] 등)
// 두 번째 인자: 실제 로직 함수 (input, userId) => Promise<Result>
// 세 번째 인자 (Optional): 옵션 객체 { url?: string, logic?: 'AND' | 'OR' }
export const createItemAction = withNonsapAuth<CreateItemInput, any>(
  ['ADD'], // 'ADD' 권한 필요
  async (input, userId) => {
    
    // ... 비즈니스 로직 ...
    
    return {
      success: true,
      data: { id: 1, ...input },
      message: "아이템이 생성되었습니다."
    };
  },
  // 옵션 예시: 특정 관리 화면의 권한을 강제로 적용
  { 
    url: '/evcp/master-data/items', 
    logic: 'AND' 
  }
);
```

### 2. 클라이언트에서 사용하기

클라이언트 컴포넌트에서는 일반적인 Server Action처럼 호출하면 됩니다.

```tsx
// app/example/page.tsx
'use client'

import { createItemAction } from "@/lib/example/service";

export default function Page() {
  const handleSubmit = async () => {
    const result = await createItemAction({ name: "Test Item", price: 1000 });
    
    if (result.success) {
      alert(result.message);
    } else {
      // 권한이 없거나 에러가 발생한 경우
      alert(result.error);
    }
  };

  return <button onClick={handleSubmit}>생성</button>;
}
```

---

## 권한 타입 (AuthAction)

`lib/nonsap/auth-service.ts`에 정의된 다음 권한 타입들을 사용할 수 있습니다.

- `'SEARCH'`: 조회
- `'ADD'`: 추가/신규작성
- `'DEL'`: 삭제
- `'SAVE'`: 저장/수정
- `'PRINT'`: 출력
- `'DOWN'`: 다운로드
- `'UP'`: 업로드
- `'APPROVAL'`: 승인
- `'PREV'`: 이전
- `'NEXT'`: 다음

## 주의사항

- **URL 감지**: 권한 체크는 현재 요청의 헤더(`x-pathname`)를 기반으로 URL을 감지하여 수행됩니다. 미들웨어에서 `x-pathname` 헤더를 설정해주어야 정상 동작합니다. (작업해뒀습니다)
- **Input 타입**: `withNonsapAuth`의 제네릭 타입으로 Input 타입을 명시해주면 타입 안전성을 확보할 수 있습니다.