Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Empty file added .codex
Empty file.
146 changes: 82 additions & 64 deletions apps/api/src/controllers/auth.ts
Original file line number Diff line number Diff line change
Expand Up @@ -76,39 +76,45 @@ export function authRoutes(fastify: FastifyInstance) {
},
},
async (request: FastifyRequest, reply: FastifyReply) => {
let { email, password, admin, name } = request.body as {
let { email, password, admin, name, language } = request.body as {
email: string;
password: string;
admin: boolean;
name: string;
language?: string;
};

const requester = await checkSession(request);

if (!requester?.isAdmin) {
return reply.code(401).send({
message: "Unauthorized",
success: false,
});
}

const normalizedEmail = email.toLowerCase().trim();

// Checks if email already exists
let record = await prisma.user.findUnique({
where: { email },
where: { email: normalizedEmail },
});

// if exists, return 400
if (record) {
return reply.code(400).send({
message: "Email already exists",
success: false,
});
}

const user = await prisma.user.create({
data: {
email,
email: normalizedEmail,
password: await bcrypt.hash(password, 10),
name,
isAdmin: admin,
language,
},
});

Expand Down Expand Up @@ -402,76 +408,88 @@ export function authRoutes(fastify: FastifyInstance) {
});
}

// Find out which config type it is, then action accordinly
switch (provider) {
case "oidc":
const config = await getOidcConfig();
if (!config) {
return reply
.code(500)
.send({ error: "OIDC configuration not found" });
}

const oidcClient = await getOidcClient(config);

// Generate codeVerifier and codeChallenge
const codeVerifier = generators.codeVerifier();
const codeChallenge = generators.codeChallenge(codeVerifier);

// Generate a random state parameter
const state = generators.state();
try {
// Find out which config type it is, then action accordinly
switch (provider) {
case "oidc":
const config = await getOidcConfig();
if (!config) {
return reply
.code(500)
.send({ error: "OIDC configuration not found" });
}

const oidcClient = await getOidcClient(config);

// Generate codeVerifier and codeChallenge
const codeVerifier = generators.codeVerifier();
const codeChallenge = generators.codeChallenge(codeVerifier);

// Generate a random state parameter
const state = generators.state();

// Store codeVerifier in cache with s
cache.set(state, {
codeVerifier: codeVerifier,
});

// Store codeVerifier in cache with s
cache.set(state, {
codeVerifier: codeVerifier,
});
// Generate authorization URL
const url = oidcClient.authorizationUrl({
scope: "openid email profile",
response_type: "code",
redirect_uri: config.redirectUri,
code_challenge: codeChallenge,
code_challenge_method: "S256", // Use 'plain' if 'S256' is not supported
state: state,
});

// Generate authorization URL
const url = oidcClient.authorizationUrl({
scope: "openid email profile",
response_type: "code",
redirect_uri: config.redirectUri,
code_challenge: codeChallenge,
code_challenge_method: "S256", // Use 'plain' if 'S256' is not supported
state: state,
});
reply.send({
type: "oidc",
success: true,
url: url,
});

reply.send({
type: "oidc",
success: true,
url: url,
});
break;
case "oauth":
const oauthProvider = await getOAuthProvider();

break;
case "oauth":
const oauthProvider = await getOAuthProvider();
if (!oauthProvider) {
return reply.code(500).send({
error: `OAuth provider ${provider} configuration not found`,
});
}

if (!oauthProvider) {
return reply.code(500).send({
error: `OAuth provider ${provider} configuration not found`,
const client = getOAuthClient({
...oauthProvider,
name: oauthProvider.name,
});
}

const client = getOAuthClient({
...oauthProvider,
name: oauthProvider.name,
});

// Generate authorization URL
const uri = client.authorizeURL({
redirect_uri: oauthProvider.redirectUri,
scope: oauthProvider.scope,
});
// Generate authorization URL
const uri = client.authorizeURL({
redirect_uri: oauthProvider.redirectUri,
scope: oauthProvider.scope,
});

reply.send({
type: "oauth",
success: true,
url: uri,
});
reply.send({
type: "oauth",
success: true,
url: uri,
});

break;
default:
break;
break;
default:
return reply.code(200).send({
success: true,
message: "SSO not enabled",
oauth: false,
});
}
} catch (err) {
return reply.code(200).send({
success: false,
message: "SSO configuration invalid",
oauth: false,
});
}
}
);
Expand Down
152 changes: 97 additions & 55 deletions apps/api/src/controllers/notebook.ts
Original file line number Diff line number Diff line change
Expand Up @@ -24,22 +24,30 @@ export function notebookRoutes(fastify: FastifyInstance) {
preHandler: requirePermission(["document::create"]),
},
async (request: FastifyRequest, reply: FastifyReply) => {
const { content, title }: any = request.body;
const user = await checkSession(request);

const data = await prisma.notes.create({
data: {
title,
note: content,
userId: user!.id,
},
});

await tracking("note_created", {});

const { id } = data;

reply.status(200).send({ success: true, id });
try {
const { content, title }: any = request.body;
const user = await checkSession(request);

if (!user) {
return reply.code(401).send({ error: "Unauthorized" });
}

const data = await prisma.notes.create({
data: {
title,
note: content,
userId: user.id,
},
});

await tracking("note_created", {});

const { id } = data;

reply.status(200).send({ success: true, id });
} catch (error) {
reply.code(401).send({ error: "Unauthorized" });
}
}
);

Expand All @@ -50,13 +58,21 @@ export function notebookRoutes(fastify: FastifyInstance) {
preHandler: requirePermission(["document::read"]),
},
async (request: FastifyRequest, reply: FastifyReply) => {
const user = await checkSession(request);
try {
const user = await checkSession(request);

const notebooks = await prisma.notes.findMany({
where: { userId: user!.id },
});
if (!user) {
return reply.code(401).send({ error: "Unauthorized" });
}

reply.status(200).send({ success: true, notebooks: notebooks });
const notebooks = await prisma.notes.findMany({
where: { userId: user.id },
});

reply.status(200).send({ success: true, notebooks: notebooks });
} catch (error) {
reply.code(401).send({ error: "Unauthorized" });
}
}
);

Expand All @@ -67,15 +83,23 @@ export function notebookRoutes(fastify: FastifyInstance) {
preHandler: requirePermission(["document::read"]),
},
async (request: FastifyRequest, reply: FastifyReply) => {
const user = await checkSession(request);
try {
const user = await checkSession(request);

if (!user) {
return reply.code(401).send({ error: "Unauthorized" });
}

const { id }: any = request.params;
const { id }: any = request.params;

const note = await prisma.notes.findUnique({
where: { userId: user!.id, id: id },
});
const note = await prisma.notes.findUnique({
where: { userId: user.id, id: id },
});

reply.status(200).send({ success: true, note });
reply.status(200).send({ success: true, note });
} catch (error) {
reply.code(401).send({ error: "Unauthorized" });
}
}
);

Expand All @@ -86,19 +110,28 @@ export function notebookRoutes(fastify: FastifyInstance) {
preHandler: requirePermission(["document::delete"]),
},
async (request: FastifyRequest, reply: FastifyReply) => {
const user = await checkSession(request);
const { id }: any = request.params;
try {
const user = await checkSession(request);

if (!user) {
return reply.code(401).send({ error: "Unauthorized" });
}

const { id }: any = request.params;

await prisma.notes.delete({
where: {
id: id,
userId: user!.id,
},
});
await prisma.notes.delete({
where: {
id: id,
userId: user.id,
},
});

await tracking("note_deleted", {});
await tracking("note_deleted", {});

reply.status(200).send({ success: true });
reply.status(200).send({ success: true });
} catch (error) {
reply.code(401).send({ error: "Unauthorized" });
}
}
);

Expand All @@ -109,24 +142,33 @@ export function notebookRoutes(fastify: FastifyInstance) {
preHandler: requirePermission(["document::update"]),
},
async (request: FastifyRequest, reply: FastifyReply) => {
const user = await checkSession(request);
const { id }: any = request.params;
const { content, title }: any = request.body;

await prisma.notes.update({
where: {
id: id,
userId: user!.id,
},
data: {
title: title,
note: content,
},
});

await tracking("note_updated", {});

reply.status(200).send({ success: true });
try {
const user = await checkSession(request);

if (!user) {
return reply.code(401).send({ error: "Unauthorized" });
}

const { id }: any = request.params;
const { content, title }: any = request.body;

await prisma.notes.update({
where: {
id: id,
userId: user.id,
},
data: {
title: title,
note: content,
},
});

await tracking("note_updated", {});

reply.status(200).send({ success: true });
} catch (error) {
reply.code(401).send({ error: "Unauthorized" });
}
}
);
}
Loading