update global (texte + logo)
This commit is contained in:
155
Linkwarden/pages/api/v1/archives/[linkId].ts
Normal file
155
Linkwarden/pages/api/v1/archives/[linkId].ts
Normal file
@ -0,0 +1,155 @@
|
||||
import type { NextApiRequest, NextApiResponse } from "next";
|
||||
import readFile from "@/lib/api/storage/readFile";
|
||||
import { prisma } from "@/lib/api/db";
|
||||
import { ArchivedFormat } from "@/types/global";
|
||||
import verifyUser from "@/lib/api/verifyUser";
|
||||
import getPermission from "@/lib/api/getPermission";
|
||||
import { UsersAndCollections } from "@prisma/client";
|
||||
import formidable from "formidable";
|
||||
import createFile from "@/lib/api/storage/createFile";
|
||||
import fs from "fs";
|
||||
import verifyToken from "@/lib/api/verifyToken";
|
||||
|
||||
export const config = {
|
||||
api: {
|
||||
bodyParser: false,
|
||||
},
|
||||
};
|
||||
|
||||
export default async function Index(req: NextApiRequest, res: NextApiResponse) {
|
||||
const linkId = Number(req.query.linkId);
|
||||
const format = Number(req.query.format);
|
||||
const isPreview = Boolean(req.query.preview);
|
||||
|
||||
let suffix: string;
|
||||
|
||||
if (format === ArchivedFormat.png) suffix = ".png";
|
||||
else if (format === ArchivedFormat.jpeg) suffix = ".jpeg";
|
||||
else if (format === ArchivedFormat.pdf) suffix = ".pdf";
|
||||
else if (format === ArchivedFormat.readability) suffix = "_readability.json";
|
||||
|
||||
//@ts-ignore
|
||||
if (!linkId || !suffix)
|
||||
return res.status(401).json({ response: "Invalid parameters." });
|
||||
|
||||
if (req.method === "GET") {
|
||||
const token = await verifyToken({ req });
|
||||
const userId = typeof token === "string" ? undefined : token?.id;
|
||||
|
||||
const collectionIsAccessible = await prisma.collection.findFirst({
|
||||
where: {
|
||||
links: {
|
||||
some: {
|
||||
id: linkId,
|
||||
},
|
||||
},
|
||||
OR: [
|
||||
{ ownerId: userId || -1 },
|
||||
{ members: { some: { userId: userId || -1 } } },
|
||||
{ isPublic: true },
|
||||
],
|
||||
},
|
||||
});
|
||||
|
||||
if (!collectionIsAccessible)
|
||||
return res
|
||||
.status(401)
|
||||
.json({ response: "You don't have access to this collection." });
|
||||
|
||||
if (isPreview) {
|
||||
const { file, contentType, status } = await readFile(
|
||||
`archives/preview/${collectionIsAccessible.id}/${linkId}.jpeg`
|
||||
);
|
||||
|
||||
res.setHeader("Content-Type", contentType).status(status as number);
|
||||
|
||||
return res.send(file);
|
||||
} else {
|
||||
const { file, contentType, status } = await readFile(
|
||||
`archives/${collectionIsAccessible.id}/${linkId + suffix}`
|
||||
);
|
||||
|
||||
res.setHeader("Content-Type", contentType).status(status as number);
|
||||
|
||||
return res.send(file);
|
||||
}
|
||||
}
|
||||
// else if (req.method === "POST") {
|
||||
// const user = await verifyUser({ req, res });
|
||||
// if (!user) return;
|
||||
|
||||
// const collectionPermissions = await getPermission({
|
||||
// userId: user.id,
|
||||
// linkId,
|
||||
// });
|
||||
|
||||
// const memberHasAccess = collectionPermissions?.members.some(
|
||||
// (e: UsersAndCollections) => e.userId === user.id && e.canCreate
|
||||
// );
|
||||
|
||||
// if (!(collectionPermissions?.ownerId === user.id || memberHasAccess))
|
||||
// return { response: "Collection is not accessible.", status: 401 };
|
||||
|
||||
// // await uploadHandler(linkId, )
|
||||
|
||||
// const MAX_UPLOAD_SIZE = Number(process.env.NEXT_PUBLIC_MAX_FILE_SIZE);
|
||||
|
||||
// const form = formidable({
|
||||
// maxFields: 1,
|
||||
// maxFiles: 1,
|
||||
// maxFileSize: MAX_UPLOAD_SIZE || 30 * 1048576,
|
||||
// });
|
||||
|
||||
// form.parse(req, async (err, fields, files) => {
|
||||
// const allowedMIMETypes = [
|
||||
// "application/pdf",
|
||||
// "image/png",
|
||||
// "image/jpg",
|
||||
// "image/jpeg",
|
||||
// ];
|
||||
|
||||
// if (
|
||||
// err ||
|
||||
// !files.file ||
|
||||
// !files.file[0] ||
|
||||
// !allowedMIMETypes.includes(files.file[0].mimetype || "")
|
||||
// ) {
|
||||
// // Handle parsing error
|
||||
// return res.status(500).json({
|
||||
// response: `Sorry, we couldn't process your file. Please ensure it's a PDF, PNG, or JPG format and doesn't exceed ${MAX_UPLOAD_SIZE}MB.`,
|
||||
// });
|
||||
// } else {
|
||||
// const fileBuffer = fs.readFileSync(files.file[0].filepath);
|
||||
|
||||
// const linkStillExists = await prisma.link.findUnique({
|
||||
// where: { id: linkId },
|
||||
// });
|
||||
|
||||
// if (linkStillExists) {
|
||||
// await createFile({
|
||||
// filePath: `archives/${collectionPermissions?.id}/${
|
||||
// linkId + suffix
|
||||
// }`,
|
||||
// data: fileBuffer,
|
||||
// });
|
||||
|
||||
// await prisma.link.update({
|
||||
// where: { id: linkId },
|
||||
// data: {
|
||||
// image: `archives/${collectionPermissions?.id}/${
|
||||
// linkId + suffix
|
||||
// }`,
|
||||
// lastPreserved: new Date().toISOString(),
|
||||
// },
|
||||
// });
|
||||
// }
|
||||
|
||||
// fs.unlinkSync(files.file[0].filepath);
|
||||
// }
|
||||
|
||||
// return res.status(200).json({
|
||||
// response: files,
|
||||
// });
|
||||
// });
|
||||
// }
|
||||
}
|
1119
Linkwarden/pages/api/v1/auth/[...nextauth].ts
Normal file
1119
Linkwarden/pages/api/v1/auth/[...nextauth].ts
Normal file
File diff suppressed because it is too large
Load Diff
100
Linkwarden/pages/api/v1/avatar/[id].ts
Normal file
100
Linkwarden/pages/api/v1/avatar/[id].ts
Normal file
@ -0,0 +1,100 @@
|
||||
import type { NextApiRequest, NextApiResponse } from "next";
|
||||
import { prisma } from "@/lib/api/db";
|
||||
import readFile from "@/lib/api/storage/readFile";
|
||||
import verifyToken from "@/lib/api/verifyToken";
|
||||
|
||||
export default async function Index(req: NextApiRequest, res: NextApiResponse) {
|
||||
const queryId = Number(req.query.id);
|
||||
|
||||
if (!queryId)
|
||||
return res
|
||||
.setHeader("Content-Type", "text/plain")
|
||||
.status(401)
|
||||
.send("Invalid parameters.");
|
||||
|
||||
const token = await verifyToken({ req });
|
||||
const userId = typeof token === "string" ? undefined : token?.id;
|
||||
|
||||
if (req.method === "GET") {
|
||||
const targetUser = await prisma.user.findUnique({
|
||||
where: {
|
||||
id: queryId,
|
||||
},
|
||||
include: {
|
||||
whitelistedUsers: true,
|
||||
},
|
||||
});
|
||||
|
||||
if (!targetUser) {
|
||||
return res
|
||||
.setHeader("Content-Type", "text/plain")
|
||||
.status(400)
|
||||
.send("File inaccessible.");
|
||||
}
|
||||
|
||||
const isInAPublicCollection = await prisma.collection.findFirst({
|
||||
where: {
|
||||
["OR"]: [
|
||||
{ ownerId: targetUser.id },
|
||||
{
|
||||
members: {
|
||||
some: {
|
||||
userId: targetUser.id,
|
||||
},
|
||||
},
|
||||
},
|
||||
],
|
||||
isPublic: true,
|
||||
},
|
||||
});
|
||||
|
||||
if (targetUser?.isPrivate && !isInAPublicCollection) {
|
||||
if (!userId) {
|
||||
return res
|
||||
.setHeader("Content-Type", "text/plain")
|
||||
.status(400)
|
||||
.send("File inaccessible.");
|
||||
}
|
||||
|
||||
const user = await prisma.user.findUnique({
|
||||
where: {
|
||||
id: userId,
|
||||
},
|
||||
include: {
|
||||
subscriptions: true,
|
||||
},
|
||||
});
|
||||
|
||||
const whitelistedUsernames = targetUser?.whitelistedUsers.map(
|
||||
(whitelistedUsername) => whitelistedUsername.username
|
||||
);
|
||||
|
||||
if (!user?.username) {
|
||||
return res
|
||||
.setHeader("Content-Type", "text/plain")
|
||||
.status(400)
|
||||
.send("File inaccessible.");
|
||||
}
|
||||
|
||||
if (
|
||||
user.username &&
|
||||
!whitelistedUsernames?.includes(user.username) &&
|
||||
targetUser.id !== user.id
|
||||
) {
|
||||
return res
|
||||
.setHeader("Content-Type", "text/plain")
|
||||
.status(400)
|
||||
.send("File inaccessible.");
|
||||
}
|
||||
}
|
||||
|
||||
const { file, contentType, status } = await readFile(
|
||||
`uploads/avatar/${queryId}.jpg`
|
||||
);
|
||||
|
||||
return res
|
||||
.setHeader("Content-Type", contentType)
|
||||
.status(status as number)
|
||||
.send(file);
|
||||
}
|
||||
}
|
28
Linkwarden/pages/api/v1/collections/[id].ts
Normal file
28
Linkwarden/pages/api/v1/collections/[id].ts
Normal file
@ -0,0 +1,28 @@
|
||||
import type { NextApiRequest, NextApiResponse } from "next";
|
||||
import getCollectionById from "@/lib/api/controllers/collections/collectionId/getCollectionById";
|
||||
import updateCollectionById from "@/lib/api/controllers/collections/collectionId/updateCollectionById";
|
||||
import deleteCollectionById from "@/lib/api/controllers/collections/collectionId/deleteCollectionById";
|
||||
import verifyUser from "@/lib/api/verifyUser";
|
||||
|
||||
export default async function collections(
|
||||
req: NextApiRequest,
|
||||
res: NextApiResponse
|
||||
) {
|
||||
const user = await verifyUser({ req, res });
|
||||
if (!user) return;
|
||||
|
||||
const collectionId = Number(req.query.id);
|
||||
|
||||
if (req.method === "GET") {
|
||||
const collections = await getCollectionById(user.id, collectionId);
|
||||
return res
|
||||
.status(collections.status)
|
||||
.json({ response: collections.response });
|
||||
} else if (req.method === "PUT") {
|
||||
const updated = await updateCollectionById(user.id, collectionId, req.body);
|
||||
return res.status(updated.status).json({ response: updated.response });
|
||||
} else if (req.method === "DELETE") {
|
||||
const deleted = await deleteCollectionById(user.id, collectionId);
|
||||
return res.status(deleted.status).json({ response: deleted.response });
|
||||
}
|
||||
}
|
24
Linkwarden/pages/api/v1/collections/index.ts
Normal file
24
Linkwarden/pages/api/v1/collections/index.ts
Normal file
@ -0,0 +1,24 @@
|
||||
import type { NextApiRequest, NextApiResponse } from "next";
|
||||
import getCollections from "@/lib/api/controllers/collections/getCollections";
|
||||
import postCollection from "@/lib/api/controllers/collections/postCollection";
|
||||
import verifyUser from "@/lib/api/verifyUser";
|
||||
|
||||
export default async function collections(
|
||||
req: NextApiRequest,
|
||||
res: NextApiResponse
|
||||
) {
|
||||
const user = await verifyUser({ req, res });
|
||||
if (!user) return;
|
||||
|
||||
if (req.method === "GET") {
|
||||
const collections = await getCollections(user.id);
|
||||
return res
|
||||
.status(collections.status)
|
||||
.json({ response: collections.response });
|
||||
} else if (req.method === "POST") {
|
||||
const newCollection = await postCollection(req.body, user.id);
|
||||
return res
|
||||
.status(newCollection.status)
|
||||
.json({ response: newCollection.response });
|
||||
}
|
||||
}
|
19
Linkwarden/pages/api/v1/dashboard/index.ts
Normal file
19
Linkwarden/pages/api/v1/dashboard/index.ts
Normal file
@ -0,0 +1,19 @@
|
||||
import type { NextApiRequest, NextApiResponse } from "next";
|
||||
import { LinkRequestQuery } from "@/types/global";
|
||||
import getDashboardData from "@/lib/api/controllers/dashboard/getDashboardData";
|
||||
import verifyUser from "@/lib/api/verifyUser";
|
||||
|
||||
export default async function links(req: NextApiRequest, res: NextApiResponse) {
|
||||
const user = await verifyUser({ req, res });
|
||||
if (!user) return;
|
||||
|
||||
if (req.method === "GET") {
|
||||
const convertedData: LinkRequestQuery = {
|
||||
sort: Number(req.query.sort as string),
|
||||
cursor: req.query.cursor ? Number(req.query.cursor as string) : undefined,
|
||||
};
|
||||
|
||||
const links = await getDashboardData(user.id, convertedData);
|
||||
return res.status(links.status).json({ response: links.response });
|
||||
}
|
||||
}
|
95
Linkwarden/pages/api/v1/links/[id]/archive/index.ts
Normal file
95
Linkwarden/pages/api/v1/links/[id]/archive/index.ts
Normal file
@ -0,0 +1,95 @@
|
||||
import type { NextApiRequest, NextApiResponse } from "next";
|
||||
import { prisma } from "@/lib/api/db";
|
||||
import verifyUser from "@/lib/api/verifyUser";
|
||||
import isValidUrl from "@/lib/shared/isValidUrl";
|
||||
import removeFile from "@/lib/api/storage/removeFile";
|
||||
import { Collection, Link } from "@prisma/client";
|
||||
|
||||
const RE_ARCHIVE_LIMIT = Number(process.env.RE_ARCHIVE_LIMIT) || 5;
|
||||
|
||||
export default async function links(req: NextApiRequest, res: NextApiResponse) {
|
||||
const user = await verifyUser({ req, res });
|
||||
if (!user) return;
|
||||
|
||||
const link = await prisma.link.findUnique({
|
||||
where: {
|
||||
id: Number(req.query.id),
|
||||
},
|
||||
include: { collection: { include: { owner: true } } },
|
||||
});
|
||||
|
||||
if (!link)
|
||||
return res.status(404).json({
|
||||
response: "Link not found.",
|
||||
});
|
||||
|
||||
if (link.collection.ownerId !== user.id)
|
||||
return res.status(401).json({
|
||||
response: "Permission denied.",
|
||||
});
|
||||
|
||||
if (req.method === "PUT") {
|
||||
if (
|
||||
link?.lastPreserved &&
|
||||
getTimezoneDifferenceInMinutes(new Date(), link?.lastPreserved) <
|
||||
RE_ARCHIVE_LIMIT
|
||||
)
|
||||
return res.status(400).json({
|
||||
response: `This link is currently being saved or has already been preserved. Please retry in ${
|
||||
RE_ARCHIVE_LIMIT -
|
||||
Math.floor(
|
||||
getTimezoneDifferenceInMinutes(new Date(), link?.lastPreserved)
|
||||
)
|
||||
} minutes or create a new one.`,
|
||||
});
|
||||
|
||||
if (!link.url || !isValidUrl(link.url))
|
||||
return res.status(200).json({
|
||||
response: "Invalid URL.",
|
||||
});
|
||||
|
||||
await deleteArchivedFiles(link);
|
||||
|
||||
return res.status(200).json({
|
||||
response: "Link is being archived.",
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
const getTimezoneDifferenceInMinutes = (future: Date, past: Date) => {
|
||||
const date1 = new Date(future);
|
||||
const date2 = new Date(past);
|
||||
|
||||
const diffInMilliseconds = Math.abs(date1.getTime() - date2.getTime());
|
||||
|
||||
const diffInMinutes = diffInMilliseconds / (1000 * 60);
|
||||
|
||||
return diffInMinutes;
|
||||
};
|
||||
|
||||
const deleteArchivedFiles = async (link: Link & { collection: Collection }) => {
|
||||
await prisma.link.update({
|
||||
where: {
|
||||
id: link.id,
|
||||
},
|
||||
data: {
|
||||
image: null,
|
||||
pdf: null,
|
||||
readable: null,
|
||||
preview: null,
|
||||
},
|
||||
});
|
||||
|
||||
await removeFile({
|
||||
filePath: `archives/${link.collection.id}/${link.id}.pdf`,
|
||||
});
|
||||
await removeFile({
|
||||
filePath: `archives/${link.collection.id}/${link.id}.png`,
|
||||
});
|
||||
await removeFile({
|
||||
filePath: `archives/${link.collection.id}/${link.id}_readability.json`,
|
||||
});
|
||||
await removeFile({
|
||||
filePath: `archives/preview/${link.collection.id}/${link.id}.png`,
|
||||
});
|
||||
};
|
31
Linkwarden/pages/api/v1/links/[id]/index.ts
Normal file
31
Linkwarden/pages/api/v1/links/[id]/index.ts
Normal file
@ -0,0 +1,31 @@
|
||||
import type { NextApiRequest, NextApiResponse } from "next";
|
||||
import deleteLinkById from "@/lib/api/controllers/links/linkId/deleteLinkById";
|
||||
import updateLinkById from "@/lib/api/controllers/links/linkId/updateLinkById";
|
||||
import getLinkById from "@/lib/api/controllers/links/linkId/getLinkById";
|
||||
import verifyUser from "@/lib/api/verifyUser";
|
||||
|
||||
export default async function links(req: NextApiRequest, res: NextApiResponse) {
|
||||
const user = await verifyUser({ req, res });
|
||||
if (!user) return;
|
||||
|
||||
if (req.method === "GET") {
|
||||
const updated = await getLinkById(user.id, Number(req.query.id));
|
||||
return res.status(updated.status).json({
|
||||
response: updated.response,
|
||||
});
|
||||
} else if (req.method === "PUT") {
|
||||
const updated = await updateLinkById(
|
||||
user.id,
|
||||
Number(req.query.id),
|
||||
req.body
|
||||
);
|
||||
return res.status(updated.status).json({
|
||||
response: updated.response,
|
||||
});
|
||||
} else if (req.method === "DELETE") {
|
||||
const deleted = await deleteLinkById(user.id, Number(req.query.id));
|
||||
return res.status(deleted.status).json({
|
||||
response: deleted.response,
|
||||
});
|
||||
}
|
||||
}
|
60
Linkwarden/pages/api/v1/links/index.ts
Normal file
60
Linkwarden/pages/api/v1/links/index.ts
Normal file
@ -0,0 +1,60 @@
|
||||
import type { NextApiRequest, NextApiResponse } from "next";
|
||||
import getLinks from "@/lib/api/controllers/links/getLinks";
|
||||
import postLink from "@/lib/api/controllers/links/postLink";
|
||||
import { LinkRequestQuery } from "@/types/global";
|
||||
import verifyUser from "@/lib/api/verifyUser";
|
||||
import deleteLinksById from "@/lib/api/controllers/links/bulk/deleteLinksById";
|
||||
import updateLinks from "@/lib/api/controllers/links/bulk/updateLinks";
|
||||
|
||||
export default async function links(req: NextApiRequest, res: NextApiResponse) {
|
||||
const user = await verifyUser({ req, res });
|
||||
if (!user) return;
|
||||
|
||||
if (req.method === "GET") {
|
||||
// Convert the type of the request query to "LinkRequestQuery"
|
||||
const convertedData: LinkRequestQuery = {
|
||||
sort: Number(req.query.sort as string),
|
||||
cursor: req.query.cursor ? Number(req.query.cursor as string) : undefined,
|
||||
collectionId: req.query.collectionId
|
||||
? Number(req.query.collectionId as string)
|
||||
: undefined,
|
||||
tagId: req.query.tagId ? Number(req.query.tagId as string) : undefined,
|
||||
pinnedOnly: req.query.pinnedOnly
|
||||
? req.query.pinnedOnly === "true"
|
||||
: undefined,
|
||||
searchQueryString: req.query.searchQueryString
|
||||
? (req.query.searchQueryString as string)
|
||||
: undefined,
|
||||
searchByName: req.query.searchByName === "true" ? true : undefined,
|
||||
searchByUrl: req.query.searchByUrl === "true" ? true : undefined,
|
||||
searchByDescription:
|
||||
req.query.searchByDescription === "true" ? true : undefined,
|
||||
searchByTextContent:
|
||||
req.query.searchByTextContent === "true" ? true : undefined,
|
||||
searchByTags: req.query.searchByTags === "true" ? true : undefined,
|
||||
};
|
||||
|
||||
const links = await getLinks(user.id, convertedData);
|
||||
return res.status(links.status).json({ response: links.response });
|
||||
} else if (req.method === "POST") {
|
||||
const newlink = await postLink(req.body, user.id);
|
||||
return res.status(newlink.status).json({
|
||||
response: newlink.response,
|
||||
});
|
||||
} else if (req.method === "PUT") {
|
||||
const updated = await updateLinks(
|
||||
user.id,
|
||||
req.body.links,
|
||||
req.body.removePreviousTags,
|
||||
req.body.newData
|
||||
);
|
||||
return res.status(updated.status).json({
|
||||
response: updated.response,
|
||||
});
|
||||
} else if (req.method === "DELETE") {
|
||||
const deleted = await deleteLinksById(user.id, req.body.linkIds);
|
||||
return res.status(deleted.status).json({
|
||||
response: deleted.response,
|
||||
});
|
||||
}
|
||||
}
|
408
Linkwarden/pages/api/v1/logins/index.ts
Normal file
408
Linkwarden/pages/api/v1/logins/index.ts
Normal file
@ -0,0 +1,408 @@
|
||||
import type { NextApiRequest, NextApiResponse } from "next";
|
||||
import * as process from "process";
|
||||
|
||||
export type ResponseData = {
|
||||
credentialsEnabled: string | undefined;
|
||||
emailEnabled: string | undefined;
|
||||
registrationDisabled: string | undefined;
|
||||
buttonAuths: {
|
||||
method: string;
|
||||
name: string;
|
||||
}[];
|
||||
};
|
||||
export default function handler(
|
||||
req: NextApiRequest,
|
||||
res: NextApiResponse<ResponseData>
|
||||
) {
|
||||
res.json(getLogins());
|
||||
}
|
||||
|
||||
export function getLogins() {
|
||||
const buttonAuths = [];
|
||||
|
||||
// 42 School
|
||||
if (process.env.NEXT_PUBLIC_FORTYTWO_ENABLED === "true") {
|
||||
buttonAuths.push({
|
||||
method: "42-school",
|
||||
name: process.env.FORTYTWO_CUSTOM_NAME ?? "42 School",
|
||||
});
|
||||
}
|
||||
// Apple
|
||||
if (process.env.NEXT_PUBLIC_APPLE_ENABLED === "true") {
|
||||
buttonAuths.push({
|
||||
method: "apple",
|
||||
name: process.env.APPLE_CUSTOM_NAME ?? "Apple",
|
||||
});
|
||||
}
|
||||
// Atlassian
|
||||
if (process.env.NEXT_PUBLIC_ATLASSIAN_ENABLED === "true") {
|
||||
buttonAuths.push({
|
||||
method: "atlassian",
|
||||
name: process.env.ATLASSIAN_CUSTOM_NAME ?? "Atlassian",
|
||||
});
|
||||
}
|
||||
// Auth0
|
||||
if (process.env.NEXT_PUBLIC_AUTH0_ENABLED === "true") {
|
||||
buttonAuths.push({
|
||||
method: "auth0",
|
||||
name: process.env.AUTH0_CUSTOM_NAME ?? "Auth0",
|
||||
});
|
||||
}
|
||||
// Authentik
|
||||
if (process.env.NEXT_PUBLIC_AUTHENTIK_ENABLED === "true") {
|
||||
buttonAuths.push({
|
||||
method: "authentik",
|
||||
name: process.env.AUTHENTIK_CUSTOM_NAME ?? "Authentik",
|
||||
});
|
||||
}
|
||||
// Battle.net
|
||||
if (process.env.NEXT_PUBLIC_BATTLENET_ENABLED === "true") {
|
||||
buttonAuths.push({
|
||||
method: "battlenet",
|
||||
name: process.env.BATTLENET_CUSTOM_NAME ?? "Battle.net",
|
||||
});
|
||||
}
|
||||
// Box
|
||||
if (process.env.NEXT_PUBLIC_BOX_ENABLED === "true") {
|
||||
buttonAuths.push({
|
||||
method: "box",
|
||||
name: process.env.BOX_CUSTOM_NAME ?? "Box",
|
||||
});
|
||||
}
|
||||
// Cognito
|
||||
if (process.env.NEXT_PUBLIC_COGNITO_ENABLED === "true") {
|
||||
buttonAuths.push({
|
||||
method: "cognito",
|
||||
name: process.env.COGNITO_CUSTOM_NAME ?? "Cognito",
|
||||
});
|
||||
}
|
||||
// Coinbase
|
||||
if (process.env.NEXT_PUBLIC_COINBASE_ENABLED === "true") {
|
||||
buttonAuths.push({
|
||||
method: "coinbase",
|
||||
name: process.env.COINBASE_CUSTOM_NAME ?? "Coinbase",
|
||||
});
|
||||
}
|
||||
// Discord
|
||||
if (process.env.NEXT_PUBLIC_DISCORD_ENABLED === "true") {
|
||||
buttonAuths.push({
|
||||
method: "discord",
|
||||
name: process.env.DISCORD_CUSTOM_NAME ?? "Discord",
|
||||
});
|
||||
}
|
||||
// Dropbox
|
||||
if (process.env.NEXT_PUBLIC_DROPBOX_ENABLED === "true") {
|
||||
buttonAuths.push({
|
||||
method: "dropbox",
|
||||
name: process.env.DROPBOX_CUSTOM_NAME ?? "Dropbox",
|
||||
});
|
||||
}
|
||||
// Duende IdentityServer6
|
||||
if (process.env.NEXT_PUBLIC_DUENDE_IDS6_ENABLED === "true") {
|
||||
buttonAuths.push({
|
||||
method: "duende-identityserver6",
|
||||
name: process.env.DUENDE_IDS6_CUSTOM_NAME ?? "DuendeIdentityServer6",
|
||||
});
|
||||
}
|
||||
// EVE Online
|
||||
if (process.env.NEXT_PUBLIC_EVEONLINE_ENABLED === "true") {
|
||||
buttonAuths.push({
|
||||
method: "eveonline",
|
||||
name: process.env.EVEONLINE_CUSTOM_NAME ?? "EVE Online",
|
||||
});
|
||||
}
|
||||
// Facebook
|
||||
if (process.env.NEXT_PUBLIC_FACEBOOK_ENABLED === "true") {
|
||||
buttonAuths.push({
|
||||
method: "facebook",
|
||||
name: process.env.FACEBOOK_CUSTOM_NAME ?? "Facebook",
|
||||
});
|
||||
}
|
||||
// FACEIT
|
||||
if (process.env.NEXT_PUBLIC_FACEIT_ENABLED === "true") {
|
||||
buttonAuths.push({
|
||||
method: "faceit",
|
||||
name: process.env.FACEIT_CUSTOM_NAME ?? "FACEIT",
|
||||
});
|
||||
}
|
||||
// Foursquare
|
||||
if (process.env.NEXT_PUBLIC_FOURSQUARE_ENABLED === "true") {
|
||||
buttonAuths.push({
|
||||
method: "foursquare",
|
||||
name: process.env.FOURSQUARE_CUSTOM_NAME ?? "Foursquare",
|
||||
});
|
||||
}
|
||||
// Freshbooks
|
||||
if (process.env.NEXT_PUBLIC_FRESHBOOKS_ENABLED === "true") {
|
||||
buttonAuths.push({
|
||||
method: "freshbooks",
|
||||
name: process.env.FRESHBOOKS_CUSTOM_NAME ?? "Freshbooks",
|
||||
});
|
||||
}
|
||||
// FusionAuth
|
||||
if (process.env.NEXT_PUBLIC_FUSIONAUTH_ENABLED === "true") {
|
||||
buttonAuths.push({
|
||||
method: "fusionauth",
|
||||
name: process.env.FUSIONAUTH_CUSTOM_NAME ?? "FusionAuth",
|
||||
});
|
||||
}
|
||||
// GitHub
|
||||
if (process.env.NEXT_PUBLIC_GITHUB_ENABLED === "true") {
|
||||
buttonAuths.push({
|
||||
method: "github",
|
||||
name: process.env.GITHUB_CUSTOM_NAME ?? "GitHub",
|
||||
});
|
||||
}
|
||||
// GitLab
|
||||
if (process.env.NEXT_PUBLIC_GITLAB_ENABLED === "true") {
|
||||
buttonAuths.push({
|
||||
method: "gitlab",
|
||||
name: process.env.GITLAB_CUSTOM_NAME ?? "GitLab",
|
||||
});
|
||||
}
|
||||
// Google
|
||||
if (process.env.NEXT_PUBLIC_GOOGLE_ENABLED === "true") {
|
||||
buttonAuths.push({
|
||||
method: "google",
|
||||
name: process.env.GOOGLE_CUSTOM_NAME ?? "Google",
|
||||
});
|
||||
}
|
||||
// HubSpot
|
||||
if (process.env.NEXT_PUBLIC_HUBSPOT_ENABLED === "true") {
|
||||
buttonAuths.push({
|
||||
method: "hubspot",
|
||||
name: process.env.HUBSPOT_CUSTOM_NAME ?? "HubSpot",
|
||||
});
|
||||
}
|
||||
// IdentityServer4
|
||||
if (process.env.NEXT_PUBLIC_IDS4_ENABLED === "true") {
|
||||
buttonAuths.push({
|
||||
method: "identity-server4",
|
||||
name: process.env.IDS4_CUSTOM_NAME ?? "IdentityServer4",
|
||||
});
|
||||
}
|
||||
// Kakao
|
||||
if (process.env.NEXT_PUBLIC_KAKAO_ENABLED === "true") {
|
||||
buttonAuths.push({
|
||||
method: "kakao",
|
||||
name: process.env.KAKAO_CUSTOM_NAME ?? "Kakao",
|
||||
});
|
||||
}
|
||||
// Keycloak
|
||||
if (process.env.NEXT_PUBLIC_KEYCLOAK_ENABLED === "true") {
|
||||
buttonAuths.push({
|
||||
method: "keycloak",
|
||||
name: process.env.KEYCLOAK_CUSTOM_NAME ?? "Keycloak",
|
||||
});
|
||||
}
|
||||
// LINE
|
||||
if (process.env.NEXT_PUBLIC_LINE_ENABLED === "true") {
|
||||
buttonAuths.push({
|
||||
method: "line",
|
||||
name: process.env.LINE_CUSTOM_NAME ?? "LINE",
|
||||
});
|
||||
}
|
||||
// LinkedIn
|
||||
if (process.env.NEXT_PUBLIC_LINKEDIN_ENABLED === "true") {
|
||||
buttonAuths.push({
|
||||
method: "linkedin",
|
||||
name: process.env.LINKEDIN_CUSTOM_NAME ?? "LinkedIn",
|
||||
});
|
||||
}
|
||||
// MailChimp
|
||||
if (process.env.NEXT_PUBLIC_MAILCHIMP_ENABLED === "true") {
|
||||
buttonAuths.push({
|
||||
method: "mailchimp",
|
||||
name: process.env.MAILCHIMP_CUSTOM_NAME ?? "Mailchimp",
|
||||
});
|
||||
}
|
||||
// Mail.ru
|
||||
if (process.env.NEXT_PUBLIC_MAILRU_ENABLED === "true") {
|
||||
buttonAuths.push({
|
||||
method: "mailru",
|
||||
name: process.env.MAILRU_CUSTOM_NAME ?? "Mail.ru",
|
||||
});
|
||||
}
|
||||
// Naver
|
||||
if (process.env.NEXT_PUBLIC_NAVER_ENABLED === "true") {
|
||||
buttonAuths.push({
|
||||
method: "naver",
|
||||
name: process.env.NAVER_CUSTOM_NAME ?? "Naver",
|
||||
});
|
||||
}
|
||||
// Netlify
|
||||
if (process.env.NEXT_PUBLIC_NETLIFY_ENABLED === "true") {
|
||||
buttonAuths.push({
|
||||
method: "netlify",
|
||||
name: process.env.NETLIFY_CUSTOM_NAME ?? "Netlify",
|
||||
});
|
||||
}
|
||||
// Okta
|
||||
if (process.env.NEXT_PUBLIC_OKTA_ENABLED === "true") {
|
||||
buttonAuths.push({
|
||||
method: "okta",
|
||||
name: process.env.OKTA_CUSTOM_NAME ?? "Okta",
|
||||
});
|
||||
}
|
||||
// OneLogin
|
||||
if (process.env.NEXT_PUBLIC_ONELOGIN_ENABLED === "true") {
|
||||
buttonAuths.push({
|
||||
method: "onelogin",
|
||||
name: process.env.ONELOGIN_CUSTOM_NAME ?? "OneLogin",
|
||||
});
|
||||
}
|
||||
// Osso
|
||||
if (process.env.NEXT_PUBLIC_OSSO_ENABLED === "true") {
|
||||
buttonAuths.push({
|
||||
method: "osso",
|
||||
name: process.env.OSSO_CUSTOM_NAME ?? "Osso",
|
||||
});
|
||||
}
|
||||
// osu!
|
||||
if (process.env.NEXT_PUBLIC_OSU_ENABLED === "true") {
|
||||
buttonAuths.push({
|
||||
method: "osu",
|
||||
name: process.env.OSU_CUSTOM_NAME ?? "Osu!",
|
||||
});
|
||||
}
|
||||
// Patreon
|
||||
if (process.env.NEXT_PUBLIC_PATREON_ENABLED === "true") {
|
||||
buttonAuths.push({
|
||||
method: "patreon",
|
||||
name: process.env.PATREON_CUSTOM_NAME ?? "Patreon",
|
||||
});
|
||||
}
|
||||
// Pinterest
|
||||
if (process.env.NEXT_PUBLIC_PINTEREST_ENABLED === "true") {
|
||||
buttonAuths.push({
|
||||
method: "pinterest",
|
||||
name: process.env.PINTEREST_CUSTOM_NAME ?? "Pinterest",
|
||||
});
|
||||
}
|
||||
// Pipedrive
|
||||
if (process.env.NEXT_PUBLIC_PIPEDRIVE_ENABLED === "true") {
|
||||
buttonAuths.push({
|
||||
method: "pipedrive",
|
||||
name: process.env.PIPEDRIVE_CUSTOM_NAME ?? "Pipedrive",
|
||||
});
|
||||
}
|
||||
// Reddit
|
||||
if (process.env.NEXT_PUBLIC_REDDIT_ENABLED === "true") {
|
||||
buttonAuths.push({
|
||||
method: "reddit",
|
||||
name: process.env.REDDIT_CUSTOM_NAME ?? "Reddit",
|
||||
});
|
||||
}
|
||||
// Salesforce
|
||||
if (process.env.NEXT_PUBLIC_SALESFORCE_ENABLED === "true") {
|
||||
buttonAuths.push({
|
||||
method: "salesforce",
|
||||
name: process.env.SALESFORCE_CUSTOM_NAME ?? "Salesforce",
|
||||
});
|
||||
}
|
||||
// Slack
|
||||
if (process.env.NEXT_PUBLIC_SLACK_ENABLED === "true") {
|
||||
buttonAuths.push({
|
||||
method: "slack",
|
||||
name: process.env.SLACK_CUSTOM_NAME ?? "Slack",
|
||||
});
|
||||
}
|
||||
// Spotify
|
||||
if (process.env.NEXT_PUBLIC_SPOTIFY_ENABLED === "true") {
|
||||
buttonAuths.push({
|
||||
method: "spotify",
|
||||
name: process.env.SPOTIFY_CUSTOM_NAME ?? "Spotify",
|
||||
});
|
||||
}
|
||||
// Strava
|
||||
if (process.env.NEXT_PUBLIC_STRAVA_ENABLED === "true") {
|
||||
buttonAuths.push({
|
||||
method: "strava",
|
||||
name: process.env.STRAVA_CUSTOM_NAME ?? "Strava",
|
||||
});
|
||||
}
|
||||
// Todoist
|
||||
if (process.env.NEXT_PUBLIC_TODOIST_ENABLED === "true") {
|
||||
buttonAuths.push({
|
||||
method: "todoist",
|
||||
name: process.env.TODOIST_CUSTOM_NAME ?? "Todoist",
|
||||
});
|
||||
}
|
||||
// Twitch
|
||||
if (process.env.NEXT_PUBLIC_TWITCH_ENABLED === "true") {
|
||||
buttonAuths.push({
|
||||
method: "twitch",
|
||||
name: process.env.TWITCH_CUSTOM_NAME ?? "Twitch",
|
||||
});
|
||||
}
|
||||
// United Effects
|
||||
if (process.env.NEXT_PUBLIC_UNITED_EFFECTS_ENABLED === "true") {
|
||||
buttonAuths.push({
|
||||
method: "united-effects",
|
||||
name: process.env.UNITED_EFFECTS_CUSTOM_NAME ?? "United Effects",
|
||||
});
|
||||
}
|
||||
// VK
|
||||
if (process.env.NEXT_PUBLIC_VK_ENABLED === "true") {
|
||||
buttonAuths.push({
|
||||
method: "vk",
|
||||
name: process.env.VK_CUSTOM_NAME ?? "VK",
|
||||
});
|
||||
}
|
||||
// Wikimedia
|
||||
if (process.env.NEXT_PUBLIC_WIKIMEDIA_ENABLED === "true") {
|
||||
buttonAuths.push({
|
||||
method: "wikimedia",
|
||||
name: process.env.WIKIMEDIA_CUSTOM_NAME ?? "Wikimedia",
|
||||
});
|
||||
}
|
||||
// Wordpress.com
|
||||
if (process.env.NEXT_PUBLIC_WORDPRESS_ENABLED === "true") {
|
||||
buttonAuths.push({
|
||||
method: "wordpress",
|
||||
name: process.env.WORDPRESS_CUSTOM_NAME ?? "WordPress.com",
|
||||
});
|
||||
}
|
||||
// Yandex
|
||||
if (process.env.NEXT_PUBLIC_YANDEX_ENABLED === "true") {
|
||||
buttonAuths.push({
|
||||
method: "yandex",
|
||||
name: process.env.YANDEX_CUSTOM_NAME ?? "Yandex",
|
||||
});
|
||||
}
|
||||
// Zitadel
|
||||
if (process.env.NEXT_PUBLIC_ZITADEL_ENABLED === "true") {
|
||||
buttonAuths.push({
|
||||
method: "zitadel",
|
||||
name: process.env.ZITADEL_CUSTOM_NAME ?? "ZITADEL",
|
||||
});
|
||||
}
|
||||
// Zoho
|
||||
if (process.env.NEXT_PUBLIC_ZOHO_ENABLED === "true") {
|
||||
buttonAuths.push({
|
||||
method: "zoho",
|
||||
name: process.env.ZOHO_CUSTOM_NAME ?? "Zoho",
|
||||
});
|
||||
}
|
||||
// Zoom
|
||||
if (process.env.NEXT_PUBLIC_ZOOM_ENABLED === "true") {
|
||||
buttonAuths.push({
|
||||
method: "zoom",
|
||||
name: process.env.ZOOM_CUSTOM_NAME ?? "Zoom",
|
||||
});
|
||||
}
|
||||
return {
|
||||
credentialsEnabled:
|
||||
process.env.NEXT_PUBLIC_CREDENTIALS_ENABLED === "true" ||
|
||||
process.env.NEXT_PUBLIC_CREDENTIALS_ENABLED === undefined
|
||||
? "true"
|
||||
: "false",
|
||||
emailEnabled:
|
||||
process.env.NEXT_PUBLIC_EMAIL_PROVIDER === "true" ? "true" : "false",
|
||||
registrationDisabled:
|
||||
process.env.NEXT_PUBLIC_DISABLE_REGISTRATION === "true"
|
||||
? "true"
|
||||
: "false",
|
||||
buttonAuths: buttonAuths,
|
||||
};
|
||||
}
|
41
Linkwarden/pages/api/v1/migration/index.ts
Normal file
41
Linkwarden/pages/api/v1/migration/index.ts
Normal file
@ -0,0 +1,41 @@
|
||||
import type { NextApiRequest, NextApiResponse } from "next";
|
||||
import exportData from "@/lib/api/controllers/migration/exportData";
|
||||
import importFromHTMLFile from "@/lib/api/controllers/migration/importFromHTMLFile";
|
||||
import importFromLinkwarden from "@/lib/api/controllers/migration/importFromLinkwarden";
|
||||
import { MigrationFormat, MigrationRequest } from "@/types/global";
|
||||
import verifyUser from "@/lib/api/verifyUser";
|
||||
|
||||
export const config = {
|
||||
api: {
|
||||
bodyParser: {
|
||||
sizeLimit: "10mb",
|
||||
},
|
||||
},
|
||||
};
|
||||
|
||||
export default async function users(req: NextApiRequest, res: NextApiResponse) {
|
||||
const user = await verifyUser({ req, res });
|
||||
if (!user) return;
|
||||
|
||||
if (req.method === "GET") {
|
||||
const data = await exportData(user.id);
|
||||
|
||||
if (data.status === 200)
|
||||
return res
|
||||
.setHeader("Content-Type", "application/json")
|
||||
.setHeader("Content-Disposition", "attachment; filename=backup.json")
|
||||
.status(data.status)
|
||||
.json(data.response);
|
||||
} else if (req.method === "POST") {
|
||||
const request: MigrationRequest = JSON.parse(req.body);
|
||||
|
||||
let data;
|
||||
if (request.format === MigrationFormat.htmlFile)
|
||||
data = await importFromHTMLFile(user.id, request.data);
|
||||
|
||||
if (request.format === MigrationFormat.linkwarden)
|
||||
data = await importFromLinkwarden(user.id, request.data);
|
||||
|
||||
if (data) return res.status(data.status).json({ response: data.response });
|
||||
}
|
||||
}
|
41
Linkwarden/pages/api/v1/payment/index.ts
Normal file
41
Linkwarden/pages/api/v1/payment/index.ts
Normal file
@ -0,0 +1,41 @@
|
||||
import type { NextApiRequest, NextApiResponse } from "next";
|
||||
import paymentCheckout from "@/lib/api/paymentCheckout";
|
||||
import { Plan } from "@/types/global";
|
||||
import { getToken } from "next-auth/jwt";
|
||||
import { prisma } from "@/lib/api/db";
|
||||
|
||||
export default async function users(req: NextApiRequest, res: NextApiResponse) {
|
||||
const STRIPE_SECRET_KEY = process.env.STRIPE_SECRET_KEY;
|
||||
const MONTHLY_PRICE_ID = process.env.MONTHLY_PRICE_ID;
|
||||
const YEARLY_PRICE_ID = process.env.YEARLY_PRICE_ID;
|
||||
|
||||
const token = await getToken({ req });
|
||||
|
||||
if (!STRIPE_SECRET_KEY || !MONTHLY_PRICE_ID || !YEARLY_PRICE_ID)
|
||||
return res.status(400).json({ response: "Payment is disabled." });
|
||||
|
||||
console.log(token);
|
||||
|
||||
if (!token?.id) return res.status(404).json({ response: "Token invalid." });
|
||||
|
||||
const email = (await prisma.user.findUnique({ where: { id: token.id } }))
|
||||
?.email;
|
||||
|
||||
if (!email) return res.status(404).json({ response: "User not found." });
|
||||
|
||||
let PRICE_ID = MONTHLY_PRICE_ID;
|
||||
|
||||
if ((Number(req.query.plan) as Plan) === Plan.monthly)
|
||||
PRICE_ID = MONTHLY_PRICE_ID;
|
||||
else if ((Number(req.query.plan) as Plan) === Plan.yearly)
|
||||
PRICE_ID = YEARLY_PRICE_ID;
|
||||
|
||||
if (req.method === "GET") {
|
||||
const users = await paymentCheckout(
|
||||
STRIPE_SECRET_KEY,
|
||||
email as string,
|
||||
PRICE_ID
|
||||
);
|
||||
return res.status(users.status).json({ response: users.response });
|
||||
}
|
||||
}
|
20
Linkwarden/pages/api/v1/public/collections/[id].ts
Normal file
20
Linkwarden/pages/api/v1/public/collections/[id].ts
Normal file
@ -0,0 +1,20 @@
|
||||
import getPublicCollection from "@/lib/api/controllers/public/collections/getPublicCollection";
|
||||
import type { NextApiRequest, NextApiResponse } from "next";
|
||||
|
||||
export default async function collection(
|
||||
req: NextApiRequest,
|
||||
res: NextApiResponse
|
||||
) {
|
||||
if (!req?.query?.id) {
|
||||
return res
|
||||
.status(401)
|
||||
.json({ response: "Please choose a valid collection." });
|
||||
}
|
||||
|
||||
if (req.method === "GET") {
|
||||
const collection = await getPublicCollection(Number(req?.query?.id));
|
||||
return res
|
||||
.status(collection.status)
|
||||
.json({ response: collection.response });
|
||||
}
|
||||
}
|
41
Linkwarden/pages/api/v1/public/collections/links/index.ts
Normal file
41
Linkwarden/pages/api/v1/public/collections/links/index.ts
Normal file
@ -0,0 +1,41 @@
|
||||
import getPublicLinksUnderCollection from "@/lib/api/controllers/public/links/getPublicLinksUnderCollection";
|
||||
import { LinkRequestQuery } from "@/types/global";
|
||||
import type { NextApiRequest, NextApiResponse } from "next";
|
||||
|
||||
export default async function collections(
|
||||
req: NextApiRequest,
|
||||
res: NextApiResponse
|
||||
) {
|
||||
if (req.method === "GET") {
|
||||
// Convert the type of the request query to "LinkRequestQuery"
|
||||
const convertedData: Omit<LinkRequestQuery, "tagId"> = {
|
||||
sort: Number(req.query.sort as string),
|
||||
cursor: req.query.cursor ? Number(req.query.cursor as string) : undefined,
|
||||
collectionId: req.query.collectionId
|
||||
? Number(req.query.collectionId as string)
|
||||
: undefined,
|
||||
pinnedOnly: req.query.pinnedOnly
|
||||
? req.query.pinnedOnly === "true"
|
||||
: undefined,
|
||||
searchQueryString: req.query.searchQueryString
|
||||
? (req.query.searchQueryString as string)
|
||||
: undefined,
|
||||
searchByName: req.query.searchByName === "true" ? true : undefined,
|
||||
searchByUrl: req.query.searchByUrl === "true" ? true : undefined,
|
||||
searchByDescription:
|
||||
req.query.searchByDescription === "true" ? true : undefined,
|
||||
searchByTextContent:
|
||||
req.query.searchByTextContent === "true" ? true : undefined,
|
||||
searchByTags: req.query.searchByTags === "true" ? true : undefined,
|
||||
};
|
||||
|
||||
if (!convertedData.collectionId) {
|
||||
return res
|
||||
.status(400)
|
||||
.json({ response: "Please choose a valid collection." });
|
||||
}
|
||||
|
||||
const links = await getPublicLinksUnderCollection(convertedData);
|
||||
return res.status(links.status).json({ response: links.response });
|
||||
}
|
||||
}
|
13
Linkwarden/pages/api/v1/public/links/[id].ts
Normal file
13
Linkwarden/pages/api/v1/public/links/[id].ts
Normal file
@ -0,0 +1,13 @@
|
||||
import getLinkById from "@/lib/api/controllers/public/links/linkId/getLinkById";
|
||||
import type { NextApiRequest, NextApiResponse } from "next";
|
||||
|
||||
export default async function link(req: NextApiRequest, res: NextApiResponse) {
|
||||
if (!req?.query?.id) {
|
||||
return res.status(401).json({ response: "Please choose a valid link." });
|
||||
}
|
||||
|
||||
if (req.method === "GET") {
|
||||
const link = await getLinkById(Number(req?.query?.id));
|
||||
return res.status(link.status).json({ response: link.response });
|
||||
}
|
||||
}
|
18
Linkwarden/pages/api/v1/public/users/[id].ts
Normal file
18
Linkwarden/pages/api/v1/public/users/[id].ts
Normal file
@ -0,0 +1,18 @@
|
||||
import type { NextApiRequest, NextApiResponse } from "next";
|
||||
import getPublicUser from "@/lib/api/controllers/public/users/getPublicUser";
|
||||
import verifyToken from "@/lib/api/verifyToken";
|
||||
|
||||
export default async function users(req: NextApiRequest, res: NextApiResponse) {
|
||||
const token = await verifyToken({ req });
|
||||
const requestingId = typeof token === "string" ? undefined : token?.id;
|
||||
|
||||
const lookupId = req.query.id as string;
|
||||
|
||||
// Check if "lookupId" is the user "id" or their "username"
|
||||
const isId = lookupId.split("").every((e) => Number.isInteger(parseInt(e)));
|
||||
|
||||
if (req.method === "GET") {
|
||||
const users = await getPublicUser(lookupId, isId, requestingId);
|
||||
return res.status(users.status).json({ response: users.response });
|
||||
}
|
||||
}
|
19
Linkwarden/pages/api/v1/tags/[id].ts
Normal file
19
Linkwarden/pages/api/v1/tags/[id].ts
Normal file
@ -0,0 +1,19 @@
|
||||
import type { NextApiRequest, NextApiResponse } from "next";
|
||||
import updeteTagById from "@/lib/api/controllers/tags/tagId/updeteTagById";
|
||||
import verifyUser from "@/lib/api/verifyUser";
|
||||
import deleteTagById from "@/lib/api/controllers/tags/tagId/deleteTagById";
|
||||
|
||||
export default async function tags(req: NextApiRequest, res: NextApiResponse) {
|
||||
const user = await verifyUser({ req, res });
|
||||
if (!user) return;
|
||||
|
||||
const tagId = Number(req.query.id);
|
||||
|
||||
if (req.method === "PUT") {
|
||||
const tags = await updeteTagById(user.id, tagId, req.body);
|
||||
return res.status(tags.status).json({ response: tags.response });
|
||||
} else if (req.method === "DELETE") {
|
||||
const tags = await deleteTagById(user.id, tagId);
|
||||
return res.status(tags.status).json({ response: tags.response });
|
||||
}
|
||||
}
|
13
Linkwarden/pages/api/v1/tags/index.ts
Normal file
13
Linkwarden/pages/api/v1/tags/index.ts
Normal file
@ -0,0 +1,13 @@
|
||||
import type { NextApiRequest, NextApiResponse } from "next";
|
||||
import getTags from "@/lib/api/controllers/tags/getTags";
|
||||
import verifyUser from "@/lib/api/verifyUser";
|
||||
|
||||
export default async function tags(req: NextApiRequest, res: NextApiResponse) {
|
||||
const user = await verifyUser({ req, res });
|
||||
if (!user) return;
|
||||
|
||||
if (req.method === "GET") {
|
||||
const tags = await getTags(user.id);
|
||||
return res.status(tags.status).json({ response: tags.response });
|
||||
}
|
||||
}
|
13
Linkwarden/pages/api/v1/tokens/[id].ts
Normal file
13
Linkwarden/pages/api/v1/tokens/[id].ts
Normal file
@ -0,0 +1,13 @@
|
||||
import type { NextApiRequest, NextApiResponse } from "next";
|
||||
import verifyUser from "@/lib/api/verifyUser";
|
||||
import deleteToken from "@/lib/api/controllers/tokens/tokenId/deleteTokenById";
|
||||
|
||||
export default async function token(req: NextApiRequest, res: NextApiResponse) {
|
||||
const user = await verifyUser({ req, res });
|
||||
if (!user) return;
|
||||
|
||||
if (req.method === "DELETE") {
|
||||
const deleted = await deleteToken(user.id, Number(req.query.id) as number);
|
||||
return res.status(deleted.status).json({ response: deleted.response });
|
||||
}
|
||||
}
|
20
Linkwarden/pages/api/v1/tokens/index.ts
Normal file
20
Linkwarden/pages/api/v1/tokens/index.ts
Normal file
@ -0,0 +1,20 @@
|
||||
import type { NextApiRequest, NextApiResponse } from "next";
|
||||
import verifyUser from "@/lib/api/verifyUser";
|
||||
import postToken from "@/lib/api/controllers/tokens/postToken";
|
||||
import getTokens from "@/lib/api/controllers/tokens/getTokens";
|
||||
|
||||
export default async function tokens(
|
||||
req: NextApiRequest,
|
||||
res: NextApiResponse
|
||||
) {
|
||||
const user = await verifyUser({ req, res });
|
||||
if (!user) return;
|
||||
|
||||
if (req.method === "POST") {
|
||||
const token = await postToken(JSON.parse(req.body), user.id);
|
||||
return res.status(token.status).json({ response: token.response });
|
||||
} else if (req.method === "GET") {
|
||||
const token = await getTokens(user.id);
|
||||
return res.status(token.status).json({ response: token.response });
|
||||
}
|
||||
}
|
59
Linkwarden/pages/api/v1/users/[id].ts
Normal file
59
Linkwarden/pages/api/v1/users/[id].ts
Normal file
@ -0,0 +1,59 @@
|
||||
import type { NextApiRequest, NextApiResponse } from "next";
|
||||
import getUserById from "@/lib/api/controllers/users/userId/getUserById";
|
||||
import updateUserById from "@/lib/api/controllers/users/userId/updateUserById";
|
||||
import deleteUserById from "@/lib/api/controllers/users/userId/deleteUserById";
|
||||
import { prisma } from "@/lib/api/db";
|
||||
import verifySubscription from "@/lib/api/verifySubscription";
|
||||
import verifyToken from "@/lib/api/verifyToken";
|
||||
|
||||
const STRIPE_SECRET_KEY = process.env.STRIPE_SECRET_KEY;
|
||||
|
||||
export default async function users(req: NextApiRequest, res: NextApiResponse) {
|
||||
const token = await verifyToken({ req });
|
||||
|
||||
if (typeof token === "string") {
|
||||
res.status(401).json({ response: token });
|
||||
return null;
|
||||
}
|
||||
|
||||
const userId = token?.id;
|
||||
|
||||
if (userId !== Number(req.query.id))
|
||||
return res.status(401).json({ response: "Permission denied." });
|
||||
|
||||
if (req.method === "GET") {
|
||||
const users = await getUserById(userId);
|
||||
return res.status(users.status).json({ response: users.response });
|
||||
}
|
||||
|
||||
if (STRIPE_SECRET_KEY) {
|
||||
const user = await prisma.user.findUnique({
|
||||
where: {
|
||||
id: token.id,
|
||||
},
|
||||
include: {
|
||||
subscriptions: true,
|
||||
},
|
||||
});
|
||||
|
||||
if (user) {
|
||||
const subscribedUser = await verifySubscription(user);
|
||||
if (!subscribedUser) {
|
||||
return res.status(401).json({
|
||||
response:
|
||||
"You are not a subscriber, feel free to reach out to us at support@linkwarden.app if you think this is an issue.",
|
||||
});
|
||||
}
|
||||
} else {
|
||||
return res.status(404).json({ response: "User not found." });
|
||||
}
|
||||
}
|
||||
|
||||
if (req.method === "PUT") {
|
||||
const updated = await updateUserById(userId, req.body);
|
||||
return res.status(updated.status).json({ response: updated.response });
|
||||
} else if (req.method === "DELETE") {
|
||||
const updated = await deleteUserById(userId, req.body);
|
||||
return res.status(updated.status).json({ response: updated.response });
|
||||
}
|
||||
}
|
9
Linkwarden/pages/api/v1/users/index.ts
Normal file
9
Linkwarden/pages/api/v1/users/index.ts
Normal file
@ -0,0 +1,9 @@
|
||||
import type { NextApiRequest, NextApiResponse } from "next";
|
||||
import postUser from "@/lib/api/controllers/users/postUser";
|
||||
|
||||
export default async function users(req: NextApiRequest, res: NextApiResponse) {
|
||||
if (req.method === "POST") {
|
||||
const response = await postUser(req, res);
|
||||
return response;
|
||||
}
|
||||
}
|
Reference in New Issue
Block a user