add sqlite compatibility + fix whitespace bug collections
This commit is contained in:
parent
264ea03e63
commit
22093c0c29
|
@ -36,6 +36,8 @@ next-env.d.ts
|
|||
|
||||
# generated files and folders
|
||||
/data
|
||||
.idea
|
||||
prisma/dev.db
|
||||
|
||||
# tests
|
||||
/tests
|
||||
|
|
|
@ -66,7 +66,6 @@ export default async function getLink(userId: number, body: string) {
|
|||
query.searchQuery && query.searchFilter?.name
|
||||
? query.searchQuery
|
||||
: undefined,
|
||||
mode: "insensitive",
|
||||
},
|
||||
},
|
||||
{
|
||||
|
@ -75,7 +74,6 @@ export default async function getLink(userId: number, body: string) {
|
|||
query.searchQuery && query.searchFilter?.url
|
||||
? query.searchQuery
|
||||
: undefined,
|
||||
mode: "insensitive",
|
||||
},
|
||||
},
|
||||
{
|
||||
|
@ -84,7 +82,6 @@ export default async function getLink(userId: number, body: string) {
|
|||
query.searchQuery && query.searchFilter?.description
|
||||
? query.searchQuery
|
||||
: undefined,
|
||||
mode: "insensitive",
|
||||
},
|
||||
},
|
||||
{
|
||||
|
@ -100,7 +97,6 @@ export default async function getLink(userId: number, body: string) {
|
|||
query.searchQuery && query.searchFilter?.tags
|
||||
? {
|
||||
contains: query.searchQuery,
|
||||
mode: "insensitive",
|
||||
}
|
||||
: undefined,
|
||||
OR: [
|
||||
|
@ -114,7 +110,6 @@ export default async function getLink(userId: number, body: string) {
|
|||
query.searchFilter?.tags
|
||||
? query.searchQuery
|
||||
: undefined,
|
||||
mode: "insensitive",
|
||||
},
|
||||
collection: {
|
||||
members: {
|
||||
|
|
|
@ -20,12 +20,15 @@ export default async function postLink(
|
|||
};
|
||||
}
|
||||
|
||||
link.collection.name = link.collection.name.trim();
|
||||
|
||||
// This has to move above we assign link.collection.name
|
||||
// Because if the link is null (write then delete text on collection)
|
||||
// It will try to do trim on empty string and will throw and error, this prevents it.
|
||||
if (!link.collection.name) {
|
||||
link.collection.name = "Unnamed Collection";
|
||||
}
|
||||
|
||||
link.collection.name = link.collection.name.trim();
|
||||
|
||||
if (link.collection.id) {
|
||||
const collectionIsAccessible = (await getPermission(
|
||||
userId,
|
||||
|
|
|
@ -17,14 +17,23 @@ export default async function getUser({
|
|||
id: params.lookupId,
|
||||
username: params.lookupUsername?.toLowerCase(),
|
||||
},
|
||||
include: {
|
||||
whitelistedUsers: {
|
||||
select: {
|
||||
username: true
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
if (!user) return { response: "User not found.", status: 404 };
|
||||
|
||||
const whitelistedUsernames = user.whitelistedUsers?.map(usernames => usernames.username);
|
||||
|
||||
if (
|
||||
!isSelf &&
|
||||
user?.isPrivate &&
|
||||
!user.whitelistedUsers.includes(username.toLowerCase())
|
||||
!whitelistedUsernames.includes(username.toLowerCase())
|
||||
) {
|
||||
return { response: "This profile is private.", status: 401 };
|
||||
}
|
||||
|
@ -33,7 +42,7 @@ export default async function getUser({
|
|||
|
||||
const data = isSelf
|
||||
? // If user is requesting its own data
|
||||
lessSensitiveInfo
|
||||
{...lessSensitiveInfo, whitelistedUsers: whitelistedUsernames}
|
||||
: {
|
||||
// If user is requesting someone elses data
|
||||
id: lessSensitiveInfo.id,
|
||||
|
|
|
@ -106,14 +106,56 @@ export default async function updateUser(
|
|||
username: user.username.toLowerCase(),
|
||||
email: user.email?.toLowerCase(),
|
||||
isPrivate: user.isPrivate,
|
||||
whitelistedUsers: user.whitelistedUsers,
|
||||
password:
|
||||
user.newPassword && user.newPassword !== ""
|
||||
? newHashedPassword
|
||||
: undefined,
|
||||
},
|
||||
include: {
|
||||
whitelistedUsers: true
|
||||
}
|
||||
});
|
||||
|
||||
|
||||
const { whitelistedUsers, password, ...userInfo } = updatedUser;
|
||||
|
||||
// If user.whitelistedUsers is not provided, we will assume the whitelistedUsers should be removed
|
||||
const newWhitelistedUsernames: string[] = user.whitelistedUsers || [];
|
||||
|
||||
// Get the current whitelisted usernames
|
||||
const currentWhitelistedUsernames: string[] = whitelistedUsers.map((user) => user.username);
|
||||
|
||||
// Find the usernames to be deleted (present in current but not in new)
|
||||
const usernamesToDelete: string[] = currentWhitelistedUsernames.filter(
|
||||
(username) => !newWhitelistedUsernames.includes(username)
|
||||
);
|
||||
|
||||
// Find the usernames to be created (present in new but not in current)
|
||||
const usernamesToCreate: string[] = newWhitelistedUsernames.filter(
|
||||
(username) => !currentWhitelistedUsernames.includes(username) && username.trim() !== ''
|
||||
);
|
||||
|
||||
// Delete whitelistedUsers that are not present in the new list
|
||||
await prisma.whitelistedUser.deleteMany({
|
||||
where: {
|
||||
userId: sessionUser.id,
|
||||
username: {
|
||||
in: usernamesToDelete,
|
||||
},
|
||||
},
|
||||
});
|
||||
|
||||
// Create new whitelistedUsers that are not in the current list, no create many ;(
|
||||
for (const username of usernamesToCreate) {
|
||||
await prisma.whitelistedUser.create({
|
||||
data: {
|
||||
username,
|
||||
userId: sessionUser.id,
|
||||
},
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
const STRIPE_SECRET_KEY = process.env.STRIPE_SECRET_KEY;
|
||||
const PRICE_ID = process.env.PRICE_ID;
|
||||
|
||||
|
@ -125,10 +167,9 @@ export default async function updateUser(
|
|||
user.email as string
|
||||
);
|
||||
|
||||
const { password, ...userInfo } = updatedUser;
|
||||
|
||||
const response: Omit<AccountSettings, "password"> = {
|
||||
...userInfo,
|
||||
whitelistedUsers: newWhitelistedUsernames,
|
||||
profilePic: `/api/avatar/${userInfo.id}?${Date.now()}`,
|
||||
};
|
||||
|
||||
|
|
|
@ -33,11 +33,16 @@ export default async function Index(req: NextApiRequest, res: NextApiResponse) {
|
|||
where: {
|
||||
id: queryId,
|
||||
},
|
||||
include: {
|
||||
whitelistedUsers: true
|
||||
}
|
||||
});
|
||||
|
||||
const whitelistedUsernames = targetUser?.whitelistedUsers.map(whitelistedUsername => whitelistedUsername.username);
|
||||
|
||||
if (
|
||||
targetUser?.isPrivate &&
|
||||
!targetUser.whitelistedUsers.includes(username)
|
||||
!whitelistedUsernames?.includes(username)
|
||||
) {
|
||||
return res
|
||||
.setHeader("Content-Type", "text/plain")
|
||||
|
|
|
@ -4,22 +4,22 @@ generator client {
|
|||
|
||||
datasource db {
|
||||
provider = "postgresql"
|
||||
url = env("DATABASE_URL")
|
||||
url = env("DATABASE_URL")
|
||||
}
|
||||
|
||||
model Account {
|
||||
id String @id @default(cuid())
|
||||
userId Int
|
||||
type String
|
||||
provider String
|
||||
providerAccountId String
|
||||
refresh_token String? @db.Text
|
||||
access_token String? @db.Text
|
||||
expires_at Int?
|
||||
token_type String?
|
||||
scope String?
|
||||
id_token String? @db.Text
|
||||
session_state String?
|
||||
id String @id @default(cuid())
|
||||
userId Int
|
||||
type String
|
||||
provider String
|
||||
providerAccountId String
|
||||
refresh_token String?
|
||||
access_token String?
|
||||
expires_at Int?
|
||||
token_type String?
|
||||
scope String?
|
||||
id_token String?
|
||||
session_state String?
|
||||
|
||||
user User @relation(fields: [userId], references: [id], onDelete: Cascade)
|
||||
|
||||
|
@ -35,29 +35,37 @@ model Session {
|
|||
}
|
||||
|
||||
model User {
|
||||
id Int @id @default(autoincrement())
|
||||
name String
|
||||
id Int @id @default(autoincrement())
|
||||
name String
|
||||
|
||||
username String? @unique
|
||||
username String? @unique
|
||||
|
||||
email String? @unique
|
||||
emailVerified DateTime?
|
||||
image String?
|
||||
email String? @unique
|
||||
emailVerified DateTime?
|
||||
image String?
|
||||
|
||||
accounts Account[]
|
||||
sessions Session[]
|
||||
|
||||
password String
|
||||
collections Collection[]
|
||||
accounts Account[]
|
||||
sessions Session[]
|
||||
|
||||
tags Tag[]
|
||||
password String
|
||||
collections Collection[]
|
||||
|
||||
pinnedLinks Link[]
|
||||
|
||||
collectionsJoined UsersAndCollections[]
|
||||
isPrivate Boolean @default(false)
|
||||
whitelistedUsers String[] @default([])
|
||||
createdAt DateTime @default(now())
|
||||
tags Tag[]
|
||||
|
||||
pinnedLinks Link[]
|
||||
|
||||
collectionsJoined UsersAndCollections[]
|
||||
isPrivate Boolean @default(false)
|
||||
whitelistedUsers whitelistedUser[]
|
||||
createdAt DateTime @default(now())
|
||||
}
|
||||
|
||||
model whitelistedUser {
|
||||
id Int @id @default(autoincrement())
|
||||
|
||||
username String @default("")
|
||||
User User? @relation(fields: [userId], references: [id])
|
||||
userId Int?
|
||||
}
|
||||
|
||||
model VerificationToken {
|
||||
|
@ -69,27 +77,26 @@ model VerificationToken {
|
|||
}
|
||||
|
||||
model Collection {
|
||||
id Int @id @default(autoincrement())
|
||||
name String
|
||||
description String @default("")
|
||||
color String @default("#0ea5e9")
|
||||
isPublic Boolean @default(false)
|
||||
id Int @id @default(autoincrement())
|
||||
name String
|
||||
description String @default("")
|
||||
color String @default("#0ea5e9")
|
||||
isPublic Boolean @default(false)
|
||||
|
||||
|
||||
owner User @relation(fields: [ownerId], references: [id])
|
||||
ownerId Int
|
||||
members UsersAndCollections[]
|
||||
links Link[]
|
||||
createdAt DateTime @default(now())
|
||||
owner User @relation(fields: [ownerId], references: [id])
|
||||
ownerId Int
|
||||
members UsersAndCollections[]
|
||||
links Link[]
|
||||
createdAt DateTime @default(now())
|
||||
|
||||
@@unique([name, ownerId])
|
||||
}
|
||||
|
||||
model UsersAndCollections {
|
||||
user User @relation(fields: [userId], references: [id])
|
||||
user User @relation(fields: [userId], references: [id])
|
||||
userId Int
|
||||
|
||||
collection Collection @relation(fields: [collectionId], references: [id])
|
||||
collection Collection @relation(fields: [collectionId], references: [id])
|
||||
collectionId Int
|
||||
|
||||
canCreate Boolean
|
||||
|
@ -100,24 +107,24 @@ model UsersAndCollections {
|
|||
}
|
||||
|
||||
model Link {
|
||||
id Int @id @default(autoincrement())
|
||||
name String
|
||||
url String
|
||||
id Int @id @default(autoincrement())
|
||||
name String
|
||||
url String
|
||||
description String @default("")
|
||||
|
||||
pinnedBy User[]
|
||||
|
||||
collection Collection @relation(fields: [collectionId], references: [id])
|
||||
collection Collection @relation(fields: [collectionId], references: [id])
|
||||
collectionId Int
|
||||
tags Tag[]
|
||||
createdAt DateTime @default(now())
|
||||
tags Tag[]
|
||||
createdAt DateTime @default(now())
|
||||
}
|
||||
|
||||
model Tag {
|
||||
id Int @id @default(autoincrement())
|
||||
name String
|
||||
links Link[]
|
||||
owner User @relation(fields: [ownerId], references: [id])
|
||||
id Int @id @default(autoincrement())
|
||||
name String
|
||||
links Link[]
|
||||
owner User @relation(fields: [ownerId], references: [id])
|
||||
ownerId Int
|
||||
|
||||
@@unique([name, ownerId])
|
||||
|
|
|
@ -36,6 +36,7 @@ export interface CollectionIncludingMembersAndLinkCount
|
|||
export interface AccountSettings extends User {
|
||||
profilePic: string;
|
||||
newPassword?: string;
|
||||
whitelistedUsers: string[]
|
||||
}
|
||||
|
||||
interface LinksIncludingTags extends Link {
|
||||
|
|
Ŝarĝante…
Reference in New Issue