Implement most of status system (still kinda bootycheeks at checking if
you're connected), fionally fix prettierrc
This commit is contained in:
parent
126acf52f3
commit
e64910d895
29 changed files with 2001 additions and 879 deletions
|
|
@ -10,141 +10,151 @@ const DAY_IN_MS = 1000 * 60 * 60 * 24;
|
|||
export const sessionCookieName = 'auth-session';
|
||||
|
||||
export function generateSessionToken() {
|
||||
const bytes = crypto.getRandomValues(new Uint8Array(18));
|
||||
const token = encodeBase64url(bytes);
|
||||
return token;
|
||||
const bytes = crypto.getRandomValues(new Uint8Array(18));
|
||||
const token = encodeBase64url(bytes);
|
||||
return token;
|
||||
}
|
||||
|
||||
export async function createSession(token: string, userId: string) {
|
||||
const sessionId = encodeHexLowerCase(sha256(new TextEncoder().encode(token)));
|
||||
const session: table.Session = {
|
||||
id: sessionId,
|
||||
userId,
|
||||
expiresAt: new Date(Date.now() + DAY_IN_MS * 30)
|
||||
};
|
||||
await db.insert(table.session).values(session);
|
||||
return session;
|
||||
const sessionId = encodeHexLowerCase(sha256(new TextEncoder().encode(token)));
|
||||
const session: table.Session = {
|
||||
id: sessionId,
|
||||
userId,
|
||||
expiresAt: new Date(Date.now() + DAY_IN_MS * 30)
|
||||
};
|
||||
await db.insert(table.session).values(session);
|
||||
return session;
|
||||
}
|
||||
|
||||
export async function validateSessionToken(token: string) {
|
||||
const sessionId = encodeHexLowerCase(sha256(new TextEncoder().encode(token)));
|
||||
const [row] = await db
|
||||
.select({
|
||||
user: {
|
||||
id: table.user.id,
|
||||
username: table.user.username,
|
||||
friends: table.user.friends,
|
||||
servers: table.user.servers,
|
||||
groups: table.user.groups,
|
||||
},
|
||||
session: table.session,
|
||||
})
|
||||
.from(table.session)
|
||||
.innerJoin(table.user, eq(table.session.userId, table.user.id))
|
||||
.where(eq(table.session.id, sessionId));
|
||||
const sessionId = encodeHexLowerCase(sha256(new TextEncoder().encode(token)));
|
||||
const [row] = await db
|
||||
.select({
|
||||
user: {
|
||||
id: table.user.id,
|
||||
username: table.user.username,
|
||||
friends: table.user.friends,
|
||||
servers: table.user.servers,
|
||||
groups: table.user.groups,
|
||||
statusOverwrite: table.user.statusOverwrite
|
||||
},
|
||||
session: table.session
|
||||
})
|
||||
.from(table.session)
|
||||
.innerJoin(table.user, eq(table.session.userId, table.user.id))
|
||||
.where(eq(table.session.id, sessionId));
|
||||
|
||||
if (!row) {
|
||||
return { session: null, user: null };
|
||||
}
|
||||
const { session, user } = row;
|
||||
if (!row) {
|
||||
return { session: null, user: null };
|
||||
}
|
||||
const { session, user } = row;
|
||||
|
||||
const sessionExpired = Date.now() >= session.expiresAt.getTime();
|
||||
if (sessionExpired) {
|
||||
await db.delete(table.session).where(eq(table.session.id, session.id));
|
||||
return { session: null, user: null };
|
||||
}
|
||||
const sessionExpired = Date.now() >= session.expiresAt.getTime();
|
||||
if (sessionExpired) {
|
||||
await db.delete(table.session).where(eq(table.session.id, session.id));
|
||||
return { session: null, user: null };
|
||||
}
|
||||
|
||||
const renewSession = Date.now() >= session.expiresAt.getTime() - DAY_IN_MS * 15;
|
||||
if (renewSession) {
|
||||
session.expiresAt = new Date(Date.now() + DAY_IN_MS * 30);
|
||||
await db
|
||||
.update(table.session)
|
||||
.set({ expiresAt: session.expiresAt })
|
||||
.where(eq(table.session.id, session.id));
|
||||
}
|
||||
const friends = (user.friends as string[]).length
|
||||
? await db
|
||||
.select({
|
||||
id: table.user.id,
|
||||
username: table.user.username,
|
||||
})
|
||||
.from(table.user)
|
||||
.where(inArray(table.user.id, (user.friends as string[])))
|
||||
: [];
|
||||
const renewSession = Date.now() >= session.expiresAt.getTime() - DAY_IN_MS * 15;
|
||||
if (renewSession) {
|
||||
session.expiresAt = new Date(Date.now() + DAY_IN_MS * 30);
|
||||
await db
|
||||
.update(table.session)
|
||||
.set({ expiresAt: session.expiresAt })
|
||||
.where(eq(table.session.id, session.id));
|
||||
}
|
||||
const friends = (user.friends as string[]).length
|
||||
? await db
|
||||
.select({
|
||||
id: table.user.id,
|
||||
username: table.user.username
|
||||
})
|
||||
.from(table.user)
|
||||
.where(inArray(table.user.id, user.friends as string[]))
|
||||
: [];
|
||||
|
||||
const servers = (user.servers as string[]).length
|
||||
? await db
|
||||
.select({
|
||||
id: table.server.id,
|
||||
name: table.server.name,
|
||||
ownerId: table.server.owner,
|
||||
})
|
||||
.from(table.server)
|
||||
.where(inArray(table.server.id, (user.servers as string[])))
|
||||
: [];
|
||||
const groups = (user.groups as string[]).length
|
||||
? await db
|
||||
.select({
|
||||
id: table.group.id,
|
||||
name: table.group.name,
|
||||
ownerId: table.group.owner,
|
||||
members: table.group.members
|
||||
})
|
||||
.from(table.group)
|
||||
.where(inArray(table.group.id, (user.groups as string[])))
|
||||
: [];
|
||||
const servers = (user.servers as string[]).length
|
||||
? await db
|
||||
.select({
|
||||
id: table.server.id,
|
||||
name: table.server.name,
|
||||
ownerId: table.server.owner
|
||||
})
|
||||
.from(table.server)
|
||||
.where(inArray(table.server.id, user.servers as string[]))
|
||||
: [];
|
||||
const groups = (user.groups as string[]).length
|
||||
? await db
|
||||
.select({
|
||||
id: table.group.id,
|
||||
name: table.group.name,
|
||||
ownerId: table.group.owner,
|
||||
members: table.group.members
|
||||
})
|
||||
.from(table.group)
|
||||
.where(inArray(table.group.id, user.groups as string[]))
|
||||
: [];
|
||||
|
||||
const friendRequests = await db
|
||||
.select({
|
||||
id: table.friendRequest.id,
|
||||
fromUser: table.friendRequest.fromUser,
|
||||
toUser: table.friendRequest.toUser,
|
||||
})
|
||||
.from(table.friendRequest)
|
||||
.where(or(eq(table.friendRequest.fromUser, user.id), eq(table.friendRequest.toUser, user.id)))
|
||||
const friendRequests = await db
|
||||
.select({
|
||||
id: table.friendRequest.id,
|
||||
fromUser: table.friendRequest.fromUser,
|
||||
toUser: table.friendRequest.toUser
|
||||
})
|
||||
.from(table.friendRequest)
|
||||
.where(or(eq(table.friendRequest.fromUser, user.id), eq(table.friendRequest.toUser, user.id)));
|
||||
|
||||
|
||||
return { session, user: {...user, servers, friends, groups: groups.map(z => { return { ...z, members: (z.members as string[]).length}}), friendRequests} };
|
||||
return {
|
||||
session,
|
||||
user: {
|
||||
...user,
|
||||
servers,
|
||||
friends,
|
||||
groups: groups.map((z) => {
|
||||
return { ...z, members: (z.members as string[]).length };
|
||||
}),
|
||||
friendRequests
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
export type SessionValidationResult = Awaited<ReturnType<typeof validateSessionToken>>;
|
||||
|
||||
export async function invalidateSession(sessionId: string) {
|
||||
await db.delete(table.session).where(eq(table.session.id, sessionId));
|
||||
await db.delete(table.session).where(eq(table.session.id, sessionId));
|
||||
}
|
||||
|
||||
export function setSessionTokenCookie(event: RequestEvent, token: string, expiresAt: Date) {
|
||||
event.cookies.set(sessionCookieName, token, {
|
||||
expires: expiresAt,
|
||||
path: '/'
|
||||
});
|
||||
event.cookies.set(sessionCookieName, token, {
|
||||
expires: expiresAt,
|
||||
path: '/'
|
||||
});
|
||||
}
|
||||
|
||||
export function deleteSessionTokenCookie(event: RequestEvent) {
|
||||
event.cookies.delete(sessionCookieName, {
|
||||
path: '/'
|
||||
});
|
||||
event.cookies.delete(sessionCookieName, {
|
||||
path: '/'
|
||||
});
|
||||
}
|
||||
|
||||
export function validateUsername(username: unknown): username is string {
|
||||
return (
|
||||
typeof username === 'string' &&
|
||||
username.length >= 3 &&
|
||||
username.length <= 31 &&
|
||||
/^[a-z0-9_-]+$/.test(username)
|
||||
);
|
||||
return (
|
||||
typeof username === 'string' &&
|
||||
username.length >= 3 &&
|
||||
username.length <= 31 &&
|
||||
/^[a-z0-9_-]+$/.test(username)
|
||||
);
|
||||
}
|
||||
|
||||
export function validatePassword(password: unknown): password is string {
|
||||
return typeof password === 'string' && password.length >= 6 && password.length <= 255;
|
||||
return typeof password === 'string' && password.length >= 6 && password.length <= 255;
|
||||
}
|
||||
|
||||
|
||||
export function validateEmail(email: unknown): email is string {
|
||||
return (
|
||||
typeof email === 'string' &&
|
||||
email.length >= 5 &&
|
||||
email.length <= 254 &&
|
||||
/^[a-z0-9._%+-]+@[a-z0-9.-]+\.[a-z]{2,}$/i.test(email)
|
||||
);
|
||||
return (
|
||||
typeof email === 'string' &&
|
||||
email.length >= 5 &&
|
||||
email.length <= 254 &&
|
||||
/^[a-z0-9._%+-]+@[a-z0-9.-]+\.[a-z]{2,}$/i.test(email)
|
||||
);
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue