This commit is contained in:
commit
33453ecc55
3475 files changed
+850363
No files matched your search
@@ -0,0 +1,110 @@
|
||||
/**
|
||||
* Copyright 2025 LY Corporation
|
||||
*
|
||||
* LY Corporation licenses this file to you under the Apache License,
|
||||
* version 2.0 (the "License"); you may not use this file except in compliance
|
||||
* with the License. You may obtain a copy of the License at:
|
||||
*
|
||||
* https://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
||||
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
||||
* License for the specific language governing permissions and limitations
|
||||
* under the License.
|
||||
*/
|
||||
import type { NextApiRequest } from 'next';
|
||||
|
||||
type StoredJwt = { accessToken?: string };
|
||||
|
||||
const supportApiBaseUrl =
|
||||
process.env.SUPPORT_API_BASE_URL ?? 'http://127.0.0.1:8010';
|
||||
|
||||
export interface SupportPrincipal {
|
||||
user_id: string;
|
||||
tenant_id: string;
|
||||
email?: string | null;
|
||||
name?: string | null;
|
||||
department?: string | null;
|
||||
phone_number?: string | null;
|
||||
is_admin?: boolean;
|
||||
is_system_admin?: boolean;
|
||||
roles?: string[];
|
||||
}
|
||||
|
||||
const SUPPORT_MANAGER_ROLES = new Set([
|
||||
'SYSTEM_ADMIN',
|
||||
'SUPER_ADMIN',
|
||||
'PROJECT_MANAGER',
|
||||
]);
|
||||
|
||||
export const isSupportAdmin = (principal: SupportPrincipal) =>
|
||||
principal.is_admin === true ||
|
||||
principal.is_system_admin === true ||
|
||||
(Array.isArray(principal.roles) &&
|
||||
principal.roles.some((role) => SUPPORT_MANAGER_ROLES.has(role)));
|
||||
|
||||
export const applySupportCommentPermissions = <
|
||||
T extends {
|
||||
author_id: string;
|
||||
author_tenant_id: string;
|
||||
},
|
||||
>(comment: T, principal: SupportPrincipal) => {
|
||||
const isAuthor =
|
||||
comment.author_id === principal.user_id &&
|
||||
comment.author_tenant_id === principal.tenant_id;
|
||||
const canManage = isSupportAdmin(principal);
|
||||
|
||||
return {
|
||||
...comment,
|
||||
can_edit: canManage || isAuthor,
|
||||
can_delete: canManage || isAuthor,
|
||||
};
|
||||
};
|
||||
|
||||
export const getSupportAuthHeaders = (
|
||||
req: NextApiRequest,
|
||||
): Record<string, string> => {
|
||||
const authorization = req.headers.authorization;
|
||||
if (authorization) return { Authorization: authorization };
|
||||
|
||||
const rawCookie = req.cookies.jwt;
|
||||
if (!rawCookie) return {};
|
||||
|
||||
try {
|
||||
const parsed = JSON.parse(decodeURIComponent(rawCookie)) as StoredJwt;
|
||||
return parsed.accessToken ?
|
||||
{ Authorization: 'Bearer ' + parsed.accessToken }
|
||||
: {};
|
||||
} catch {
|
||||
return {};
|
||||
}
|
||||
};
|
||||
|
||||
export const getSupportPrincipal = async (
|
||||
req: NextApiRequest,
|
||||
): Promise<SupportPrincipal | null> => {
|
||||
const headers = getSupportAuthHeaders(req);
|
||||
if (!headers.Authorization) return null;
|
||||
|
||||
try {
|
||||
const response = await fetch(`${supportApiBaseUrl}/api/access/me`, {
|
||||
headers,
|
||||
});
|
||||
if (!response.ok) return null;
|
||||
|
||||
const data = (await response.json()) as Partial<SupportPrincipal>;
|
||||
if (
|
||||
typeof data.user_id !== 'string' ||
|
||||
typeof data.tenant_id !== 'string' ||
|
||||
!data.user_id ||
|
||||
!data.tenant_id
|
||||
) {
|
||||
return null;
|
||||
}
|
||||
|
||||
return data as SupportPrincipal;
|
||||
} catch {
|
||||
return null;
|
||||
}
|
||||
};
|
||||
Reference in new issue
Block a user