Skip to content

Commit 15c0bed

Browse files
authored
v0.3.1 (#28)
1 parent e4940bc commit 15c0bed

File tree

4 files changed

+415
-0
lines changed

4 files changed

+415
-0
lines changed
Lines changed: 191 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,191 @@
1+
import { PUBLIC_IS_LOCAL } from '$env/static/public';
2+
import { JAMAI_URL, JAMAI_SERVICE_KEY } from '$env/static/private';
3+
import { json } from '@sveltejs/kit';
4+
import { projectIDPattern } from '$lib/constants.js';
5+
import logger, { APIError } from '$lib/logger.js';
6+
import type { UserRead } from '$lib/types.js';
7+
8+
const headers = {
9+
Authorization: `Bearer ${JAMAI_SERVICE_KEY}`
10+
};
11+
12+
export const GET = async ({ cookies, locals, url }) => {
13+
const activeOrganizationId = cookies.get('activeOrganizationId');
14+
15+
if (PUBLIC_IS_LOCAL === 'false') {
16+
if (!activeOrganizationId) {
17+
return json(new APIError('No active organization'), { status: 400 });
18+
}
19+
20+
//* Verify user perms
21+
if (!locals.user) {
22+
return json(new APIError('Unauthorized'), { status: 401 });
23+
}
24+
25+
const userApiRes = await fetch(`${JAMAI_URL}/api/admin/backend/v1/users/${locals.user.sub}`, {
26+
headers
27+
});
28+
const userApiBody = (await userApiRes.json()) as UserRead;
29+
if (userApiRes.ok) {
30+
const targetOrg = userApiBody.member_of.find(
31+
(org) => org.organization_id === activeOrganizationId
32+
);
33+
if (!targetOrg) {
34+
return json(new APIError('Forbidden'), { status: 403 });
35+
}
36+
} else {
37+
logger.error('PROJECT_LIST_GETUSER', userApiBody);
38+
return json(new APIError('Failed to get user info', userApiBody as any), {
39+
status: userApiRes.status
40+
});
41+
}
42+
}
43+
44+
const searchParams = new URLSearchParams({ organization_id: activeOrganizationId ?? '' });
45+
url.searchParams.forEach((value, key) => {
46+
if (key === 'organization_id' && PUBLIC_IS_LOCAL === 'false') return;
47+
searchParams.set(key, value);
48+
});
49+
50+
const projectsListRes = await fetch(`${JAMAI_URL}/api/admin/org/v1/projects?${searchParams}`, {
51+
headers
52+
});
53+
const projectsListBody = await projectsListRes.json();
54+
55+
if (!projectsListRes.ok) {
56+
logger.error('PROJECT_LIST_LIST', projectsListBody);
57+
return json(new APIError('Failed to get projects list', projectsListBody), {
58+
status: projectsListRes.status
59+
});
60+
} else {
61+
return json(projectsListBody);
62+
}
63+
};
64+
65+
export const POST = async ({ cookies, fetch, locals, request }) => {
66+
const activeOrganizationId = cookies.get('activeOrganizationId');
67+
68+
const { name: project_name } = await request.json();
69+
if (!project_name || typeof project_name !== 'string' || project_name.trim() === '') {
70+
return json(new APIError('Invalid project name'), { status: 400 });
71+
}
72+
73+
if (!projectIDPattern.test(project_name)) {
74+
return json(
75+
new APIError(
76+
'Project name must contain only alphanumeric characters and underscores/hyphens/spaces/periods, and start and end with alphanumeric characters, between 2 and 100 characters.'
77+
),
78+
{ status: 400 }
79+
);
80+
}
81+
82+
if (PUBLIC_IS_LOCAL === 'false') {
83+
//* Verify user perms
84+
if (!locals.user) {
85+
return json(new APIError('Unauthorized'), { status: 401 });
86+
}
87+
88+
const userApiRes = await fetch(`${JAMAI_URL}/api/admin/backend/v1/users/${locals.user.sub}`, {
89+
headers
90+
});
91+
const userApiBody = (await userApiRes.json()) as UserRead;
92+
if (userApiRes.ok) {
93+
const targetOrg = userApiBody.member_of.find(
94+
(org) => org.organization_id === activeOrganizationId
95+
);
96+
if (!targetOrg || (targetOrg.role !== 'admin' && targetOrg.role !== 'member')) {
97+
return json(new APIError('Forbidden'), { status: 403 });
98+
}
99+
} else {
100+
logger.error('PROJECT_CREATE_GETUSER', userApiBody);
101+
return json(new APIError('Failed to get user info', userApiBody as any), {
102+
status: userApiRes.status
103+
});
104+
}
105+
}
106+
107+
const createProjectRes = await fetch(`${JAMAI_URL}/api/admin/org/v1/projects`, {
108+
method: 'POST',
109+
headers: {
110+
...headers,
111+
'Content-Type': 'application/json'
112+
},
113+
body: JSON.stringify({
114+
name: project_name,
115+
organization_id: activeOrganizationId
116+
})
117+
});
118+
119+
const createProjectBody = await createProjectRes.json();
120+
if (!createProjectRes.ok) {
121+
logger.error('PROJECT_CREATE_CREATE', createProjectBody);
122+
return json(new APIError('Failed to create project', createProjectBody), {
123+
status: createProjectRes.status
124+
});
125+
} else {
126+
return json(createProjectBody);
127+
}
128+
};
129+
130+
export const PATCH = async ({ locals, request }) => {
131+
const { id: projectId, name: project_name } = await request.json();
132+
if (!project_name || typeof project_name !== 'string' || project_name.trim() === '') {
133+
return json(new APIError('Invalid project name'), { status: 400 });
134+
}
135+
136+
if (PUBLIC_IS_LOCAL === 'false') {
137+
if (!locals.user) {
138+
return json(new APIError('Unauthorized'), { status: 401 });
139+
}
140+
141+
const projectApiRes = await fetch(`${JAMAI_URL}/api/admin/org/v1/projects/${projectId}`, {
142+
headers
143+
});
144+
const projectApiBody = await projectApiRes.json();
145+
146+
if (!projectApiRes.ok) {
147+
logger.error('PROJECT_PATCH_GETPROJ', projectApiBody);
148+
}
149+
150+
const userApiRes = await fetch(`${JAMAI_URL}/api/admin/backend/v1/users/${locals.user.sub}`, {
151+
headers
152+
});
153+
const userApiBody = (await userApiRes.json()) as UserRead;
154+
155+
if (userApiRes.ok) {
156+
const targetOrg = userApiBody.member_of.find(
157+
(org) => org.organization_id === projectApiBody.organization_id
158+
);
159+
if (!targetOrg || targetOrg.role !== 'admin') {
160+
return json(new APIError('Forbidden'), { status: 403 });
161+
}
162+
} else {
163+
logger.error('PROJECT_PATCH_GETUSER', userApiBody);
164+
return json(new APIError('Failed to get user info', userApiBody as any), {
165+
status: userApiRes.status
166+
});
167+
}
168+
}
169+
170+
const patchProjectRes = await fetch(`${JAMAI_URL}/api/admin/org/v1/projects`, {
171+
method: 'PATCH',
172+
headers: {
173+
...headers,
174+
'Content-Type': 'application/json'
175+
},
176+
body: JSON.stringify({
177+
id: projectId,
178+
name: project_name
179+
})
180+
});
181+
182+
const patchProjectBody = await patchProjectRes.json();
183+
if (!patchProjectRes.ok) {
184+
logger.error('PROJECT_PATCH_PATCH', patchProjectBody);
185+
return json(new APIError('Failed to update project', patchProjectBody as any), {
186+
status: patchProjectRes.status
187+
});
188+
} else {
189+
return json({ ok: true });
190+
}
191+
};
Lines changed: 93 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,93 @@
1+
import { PUBLIC_IS_LOCAL } from '$env/static/public';
2+
import { JAMAI_URL, JAMAI_SERVICE_KEY } from '$env/static/private';
3+
import { json } from '@sveltejs/kit';
4+
import logger, { APIError } from '$lib/logger.js';
5+
import type { Project, UserRead } from '$lib/types.js';
6+
7+
const headers = {
8+
Authorization: `Bearer ${JAMAI_SERVICE_KEY}`
9+
};
10+
11+
export const GET = async ({ locals, params }) => {
12+
if (PUBLIC_IS_LOCAL === 'false') {
13+
if (!locals.user) {
14+
return json(new APIError('Unauthorized'), { status: 401 });
15+
}
16+
}
17+
18+
const projectRes = await fetch(`${JAMAI_URL}/api/admin/org/v1/projects/${params.project_id}`, {
19+
headers
20+
});
21+
const projectBody = await projectRes.json();
22+
23+
if (projectRes.ok) {
24+
if (
25+
PUBLIC_IS_LOCAL !== 'false' ||
26+
(projectBody as Project).organization.members?.find(
27+
(user) => user.user_id === locals.user?.sub
28+
)
29+
) {
30+
return json(projectBody);
31+
} else {
32+
return json(new APIError('Project not found'), { status: 404 });
33+
}
34+
} else {
35+
return json(new APIError('Failed to get project', projectBody as any), {
36+
status: projectRes.status
37+
});
38+
}
39+
};
40+
41+
export const DELETE = async ({ locals, params }) => {
42+
const projectId = params.project_id;
43+
44+
if (PUBLIC_IS_LOCAL === 'false') {
45+
//* Verify user perms
46+
if (!locals.user) {
47+
return json(new APIError('Unauthorized'), { status: 401 });
48+
}
49+
50+
const projectApiRes = await fetch(`${JAMAI_URL}/api/admin/org/v1/projects/${projectId}`, {
51+
headers
52+
});
53+
const projectApiBody = await projectApiRes.json();
54+
55+
if (!projectApiRes.ok) {
56+
logger.error('PROJECT_DELETE_GETPROJ', projectApiBody);
57+
}
58+
59+
const userApiRes = await fetch(`${JAMAI_URL}/api/admin/backend/v1/users/${locals.user.sub}`, {
60+
headers
61+
});
62+
const userApiBody = (await userApiRes.json()) as UserRead;
63+
64+
if (userApiRes.ok) {
65+
const targetOrg = userApiBody.member_of.find(
66+
(org) => org.organization_id === projectApiBody.organization_id
67+
);
68+
if (!targetOrg || targetOrg.role !== 'admin') {
69+
return json(new APIError('Forbidden'), { status: 403 });
70+
}
71+
} else {
72+
logger.error('PROJECT_DELETE_GETUSER', userApiBody);
73+
return json(new APIError('Failed to get user info', userApiBody as any), {
74+
status: userApiRes.status
75+
});
76+
}
77+
}
78+
79+
const deleteProjectRes = await fetch(`${JAMAI_URL}/api/admin/org/v1/projects/${projectId}`, {
80+
method: 'DELETE',
81+
headers
82+
});
83+
84+
const deleteProjectBody = await deleteProjectRes.json();
85+
if (!deleteProjectRes.ok) {
86+
logger.error('PROJECT_DELETE_DELETE', deleteProjectBody);
87+
return json(new APIError('Failed to delete project', deleteProjectBody as any), {
88+
status: deleteProjectRes.status
89+
});
90+
} else {
91+
return json({ ok: true });
92+
}
93+
};
Lines changed: 65 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,65 @@
1+
import { PUBLIC_IS_LOCAL } from '$env/static/public';
2+
import { JAMAI_URL, JAMAI_SERVICE_KEY } from '$env/static/private';
3+
import { json } from '@sveltejs/kit';
4+
import logger, { APIError } from '$lib/logger.js';
5+
import type { UserRead } from '$lib/types.js';
6+
7+
const headers = {
8+
Authorization: `Bearer ${JAMAI_SERVICE_KEY}`
9+
};
10+
11+
export const GET = async ({ locals, params }) => {
12+
const projectId = params.project_id;
13+
14+
if (PUBLIC_IS_LOCAL === 'false') {
15+
//* Verify user perms
16+
if (!locals.user) {
17+
return json(new APIError('Unauthorized'), { status: 401 });
18+
}
19+
20+
const projectApiRes = await fetch(`${JAMAI_URL}/api/admin/org/v1/projects/${projectId}`, {
21+
headers
22+
});
23+
const projectApiBody = await projectApiRes.json();
24+
25+
if (!projectApiRes.ok) {
26+
logger.error('PROJECT_EXPORT_GETPROJ', projectApiBody);
27+
}
28+
29+
const userApiRes = await fetch(`${JAMAI_URL}/api/admin/backend/v1/users/${locals.user.sub}`, {
30+
headers
31+
});
32+
const userApiBody = (await userApiRes.json()) as UserRead;
33+
34+
if (userApiRes.ok) {
35+
const targetOrg = userApiBody.member_of.find(
36+
(org) => org.organization_id === projectApiBody.organization_id
37+
);
38+
if (!targetOrg) {
39+
return json(new APIError('Forbidden'), { status: 403 });
40+
}
41+
} else {
42+
logger.error('PROJECT_EXPORT_GETUSER', userApiBody);
43+
return json(new APIError('Failed to get user info', userApiBody as any), {
44+
status: userApiRes.status
45+
});
46+
}
47+
}
48+
49+
const exportProjectRes = await fetch(
50+
`${JAMAI_URL}/api/admin/org/v1/projects/${projectId}/export`,
51+
{
52+
headers
53+
}
54+
);
55+
56+
if (!exportProjectRes.ok) {
57+
const exportProjectBody = await exportProjectRes.json();
58+
logger.error('PROJECT_EXPORT_EXPORT', exportProjectBody);
59+
return json(new APIError('Failed to export project', exportProjectBody as any), {
60+
status: exportProjectRes.status
61+
});
62+
} else {
63+
return exportProjectRes;
64+
}
65+
};

0 commit comments

Comments
 (0)