blob: 04a31bccb8ddebbf4d7837f6e3c94acd73076831 (
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
|
"use server";
import { SignJWT, jwtVerify } from "jose";
// JWT_SECRET 환경변수 검증
if (!process.env.JWT_SECRET) {
console.error("JWT_SECRET environment variable is not set. Please configure JWT_SECRET in your environment variables.");
throw new Error("JWT_SECRET environment variable is required");
}
const secretKey = process.env.JWT_SECRET;
const key = new TextEncoder().encode(secretKey);
export interface TechVendorInvitationPayload {
vendorId: number;
vendorName: string;
email: string;
vendorType: "조선" | "해양TOP" | "해양HULL" | ("조선" | "해양TOP" | "해양HULL")[];
type: "tech-vendor-invitation";
expiresAt: number;
}
/**
* 기술영업 벤더 초대용 일회성 토큰 생성
*/
export async function createTechVendorInvitationToken(payload: {
vendorId: number;
vendorName: string;
email: string;
vendorType: "조선" | "해양TOP" | "해양HULL" | ("조선" | "해양TOP" | "해양HULL")[];
}): Promise<string> {
const expiresAt = Date.now() + 7 * 24 * 60 * 60 * 1000; // 7일
const token = await new SignJWT({
vendorId: payload.vendorId,
vendorName: payload.vendorName,
email: payload.email,
type: "tech-vendor-invitation",
vendorType: payload.vendorType,
expiresAt,
})
.setProtectedHeader({ alg: "HS256" })
.setIssuedAt()
.setExpirationTime("7d")
.sign(key);
return token;
}
/**
* 기술영업 벤더 초대 토큰 검증
*/
export async function verifyTechVendorInvitationToken(
token: string
): Promise<TechVendorInvitationPayload | null> {
try {
const { payload } = await jwtVerify(token, key);
const tokenPayload = payload as unknown as TechVendorInvitationPayload;
// 토큰 타입 검증
if (tokenPayload.type !== "tech-vendor-invitation") {
console.error("Invalid token type:", tokenPayload.type);
return null;
}
// 만료 시간 검증
if (Date.now() > tokenPayload.expiresAt) {
console.error("Token has expired");
return null;
}
return tokenPayload;
} catch (error) {
console.error("Token verification failed:", error);
return null;
}
}
/**
* 초대 토큰을 포함한 가입 URL 생성
*/
export async function createTechVendorSignupUrl(token: string): Promise<string> {
const baseUrl = process.env.NEXT_PUBLIC_URL || "http://localhost:3000";
return `${baseUrl}/partners/tech-signup?token=${token}`;
}
|