Skip to content

Commit

Permalink
Merge branch 'develop'
Browse files Browse the repository at this point in the history
  • Loading branch information
yunochi committed Nov 25, 2024
2 parents 1073927 + afae7ee commit 12864e6
Show file tree
Hide file tree
Showing 16 changed files with 368 additions and 261 deletions.
2 changes: 1 addition & 1 deletion src/app/api/_utils/fetchUsername.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ export async function fetchNameWithEmoji(fetchUserNameReq: fetchNameWithEmojiReq
body: JSON.stringify(fetchUserNameReq),
});
if (!res.ok) {
logger.error(`fail to get username with emojis `, res.status, res.statusText);
logger.error(`fail to get username with emojis `, res.status, await res.text());
throw new Error('fail to get username with emojis');
}
const body: fetchNameWithEmojiResDto = await res.json();
Expand Down
3 changes: 3 additions & 0 deletions src/app/api/_utils/jwt/generate-jwt.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,9 @@

import { SignJWT } from 'jose';
import { jwtPayload } from './jwtPayload';
import { Logger } from '@/utils/logger/Logger';

const logger = new Logger('generateJwt');
export async function generateJwt(hostname: string, handle: string, jwtIndex: number) {
const alg = 'HS256';
const secret = new TextEncoder().encode(process.env.JWT_SECRET);
Expand All @@ -20,5 +22,6 @@ export async function generateJwt(hostname: string, handle: string, jwtIndex: nu
.setAudience('urn:example:audience')
.setExpirationTime('7d')
.sign(secret);
logger.log(`Make new JWT: ${JSON.stringify(jwtPayload)}`);
return jwtToken;
}
4 changes: 2 additions & 2 deletions src/app/api/db/create-question/route.ts
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ export async function POST(req: NextRequest) {
req_limit: 10,
});
if (limited) {
return sendApiError(429, '요청 제한에 도달했습니다!');
return sendApiError(429, '요청 제한에 도달했습니다! 잠시후 다시 시도해 주세요!');
}
} else {
const limiter = RateLimiterService.getLimiter();
Expand All @@ -34,7 +34,7 @@ export async function POST(req: NextRequest) {
req_limit: 10,
});
if (limited) {
return sendApiError(429, '요청 제한에 도달했습니다!');
return sendApiError(429, '요청 제한에 도달했습니다! 잠시후 다시 시도해 주세요!');
}
}

Expand Down
3 changes: 2 additions & 1 deletion src/app/api/web/refresh-token/route.ts
Original file line number Diff line number Diff line change
Expand Up @@ -47,14 +47,15 @@ export async function POST(req: NextRequest) {
const user = await prisma.user.findUniqueOrThrow({ where: { handle: tokenPayload.handle } });

try {
logger.log('Try refresh JWT...');
await refreshAndReValidateToken(user);
const jwtToken = await generateJwt(user.hostName, user.handle, user.jwtIndex);
cookieStore.set('jwtToken', jwtToken, {
expires: Date.now() + 1000 * 60 * 60 * 24 * 7,
httpOnly: true,
});
} catch (err) {
logger.warn('User가 미스키/마스토돈에서 앱 권한을 Revoke한것 같아요. JWT index를 올릴게요. 자세한 정보:', err);
logger.warn('User Revoked Access token. JWT를 Revoke합니다... Detail:', err);
await prisma.user.update({where: {handle: user.handle}, data: {jwtIndex: (user.jwtIndex + 1)}});
return sendApiError(401, `Refresh user failed!! ${err}`);
}
Expand Down
11 changes: 11 additions & 0 deletions src/app/index.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -56,3 +56,14 @@ export interface postQuestion {
answeredPerson: user;
answeredPersonHandle: string;
}

export interface DBpayload {
account: user['account'];
accountLower: user['accountLower'];
hostName: user['hostName'];
handle: user['handle'];
name: profile['name'];
avatarUrl: profile['avatarUrl'];
accessToken: user['token'];
userId: user['userId'];
};
34 changes: 5 additions & 29 deletions src/app/main/_header.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -6,13 +6,8 @@ import { FaUser } from 'react-icons/fa';
import { userProfileMeDto } from '../_dto/fetch-profile/Profile.dto';
import DialogModalTwoButton from '../_components/modalTwoButton';
import DialogModalOneButton from '../_components/modalOneButton';
import { RefreshTokenReqDto } from '../_dto/refresh-token/refresh-token.dto';

const logout = async () => {
await fetch('/api/web/logout');
localStorage.removeItem('user_handle');
window.location.reload();
};
import { refreshJwt } from '@/utils/refreshJwt/refresh-jwt-token';
import { logout } from '@/utils/logout/logout';

export default function MainHeader() {
const [user, setUser] = useState<userProfileMeDto>();
Expand All @@ -21,7 +16,6 @@ export default function MainHeader() {

const fetchMyProfile = async () => {
const user_handle = localStorage.getItem('user_handle');
const last_token_refresh = Number.parseInt(localStorage.getItem('last_token_refresh') ?? '0');
const now = Math.ceil(Date.now() / 1000);

if (user_handle) {
Expand All @@ -34,28 +28,10 @@ export default function MainHeader() {
}
return;
}
// FIXME: 3600초 대신 적당한 시간으로 고치기
// JWT 리프레시로부터 1시간이 지난 경우 refresh 시도
const last_token_refresh = Number.parseInt(localStorage.getItem('last_token_refresh') ?? '0');
if (now - last_token_refresh > 3600) {
localStorage.setItem('last_token_refresh', `${now}`);
try {
const req: RefreshTokenReqDto = {
handle: user_handle,
last_refreshed_time: last_token_refresh,
}
const res = await fetch('/api/web/refresh-token', {
method: 'POST',
headers: {
'content-type': 'application/json'
},
body: JSON.stringify(req),
});
if (res.status === 401 || res.status === 403) {
alert(`마스토돈/미스키 에서 앱 인증이 해제되었어요! ${await res.text()}`);
await logout();
}
} catch (err) {
console.error(err);
}
await refreshJwt();
}
const data = await res.json();
return data;
Expand Down
Loading

0 comments on commit 12864e6

Please sign in to comment.