#Custom convex auth adapter

1 messages · Page 1 of 1 (latest)

oblique stream
#

Give me a base convex auth adapter I can use as a template for creating my own. I will use svelte and convex. Will implements auth on my own.

Example of my implementation

import { db } from "./db.js";

export function generateSessionToken(): string {
// TODO
}

export async function createSession(token: string, userId: number): Promise<Session> {
// TODO
}

export async function validateSessionToken(token: string): Promise<SessionValidationResult> {
// TODO
}

export async function invalidateSession(sessionId: string): Promise<void> {
// TODO
}

export type SessionValidationResult =
| { session: Session; user: User }
| { session: null; user: null };

export interface Session {
id: string;
userId: number;
expiresAt: Date;
}

export interface User {
id: number;
}

And then for cookies:

import type { RequestEvent } from "@sveltejs/kit";

// ...

export function setSessionTokenCookie(event: RequestEvent, token: string, expiresAt: Date): void {
event.cookies.set("session", token, {
httpOnly: true,
sameSite: "lax",
expires: expiresAt,
path: "/"
});
}

export function deleteSessionTokenCookie(event: RequestEvent): void {
event.cookies.set("session", "", {
httpOnly: true,
sameSite: "lax",
maxAge: 0,
path: "/"
});
}

slate flumeBOT
#

Hi @oblique stream. I'm kapa.ai, your friendly support bot. I will try to answer your question by searching through the knowledge base. :wave:

#

Sure, I can provide you with a base Convex auth adapter that you can use as a template for creating your own. Here's an example of a Convex adapter for Auth.js (NextAuth) from the Convex documentation. You can modify this to suit your needs:

import { v } from "convex/values";
import { mutation, query } from "./_generated/server";
import {
  accountSchema,
  authenticatorSchema,
  sessionSchema,
  userSchema,
  verificationTokenSchema,
} from "./schema";

const adapterQuery = customQuery(query, {
  args: { secret: v.string() },
  input: async (_ctx, { secret }) => {
    checkSecret(secret);
    return { ctx: {}, args: {} };
  },
});

const adapterMutation = customMutation(mutation, {
  args: { secret: v.string() },
  input: async (_ctx, { secret }) => {
    checkSecret(secret);
    return { ctx: {}, args: {} };
  },
});

function checkSecret(secret: string) {
	if (process.env.CONVEX_AUTH_ADAPTER_SECRET === undefined) {
    throw new Error(
      "Missing CONVEX_AUTH_ADAPTER_SECRET Convex environment variable",
    );
  }
  if (secret !== process.env.CONVEX_AUTH_ADAPTER_SECRET) {
    throw new Error("Adapter API called without correct secret value");
  }
}

export const createAuthenticator = adapterMutation({
  args: { authenticator: v.object(authenticatorSchema) },
  handler: async (ctx, args) => {
    return await ctx.db.insert("authenticators", args.authenticator);
  },
});

export const createSession = adapterMutation({
  args: { session: v.object(sessionSchema) },
  handler: async (ctx, { session }) => {
    return await ctx.db.insert("sessions", session);
  },
});

This is a simplified version of the adapter. You can find the full version in the Convex documentation (https://stack.convex.dev/nextauth-adapter#endpoints).

#

Please note that this is a Convex adapter for Auth.js (NextAuth), and you might need to adjust it to fit your Svelte application. You can also refer to the ConvexCredentials (https://labs.convex.dev/auth/api_reference/providers/ConvexCredentials) provider for a custom authentication implementation.

For handling cookies in Svelte, your implementation seems correct. You can use the set method of event.cookies to set a cookie and its properties, and to delete a cookie, you can set its maxAge to 0.

Remember to secure your cookies by setting httpOnly to true and sameSite to lax or strict, as you've done in your example. This will help prevent cross-site scripting (XSS) and cross-site request forgery (CSRF) attacks.

Note: you can ask me a follow up question by @ mentioning me again :speech_balloon:

#

@oblique stream Kapa.ai is still learning and improving, please let me know how I did by reacting below.

oblique stream
#

@slate flume
I gave you my implementation structure, create the auth adapter for me

slate flumeBOT
#

Let me check the knowledge base for you again. One moment! :books:

#

I'm sorry, but the knowledge sources provided do not contain enough information to create a complete custom Convex auth adapter based on your implementation structure.

However, I can guide you on how you might structure your adapter based on the Convex Adapter for Auth.js (NextAuth) example provided in the knowledge sources. Here's a simplified example:

import { v } from "convex/values";
import { mutation } from "./_generated/server";
import { sessionSchema } from "./schema";

const adapterMutation = customMutation(mutation, {
  args: { secret: v.string() },
  input: async (_ctx, { secret }) => {
    checkSecret(secret);
    return { ctx: {}, args: {} };
  },
});

function checkSecret(secret: string) {
	if (process.env.CONVEX_AUTH_ADAPTER_SECRET === undefined) {
    throw new Error(
      "Missing CONVEX_AUTH_ADAPTER_SECRET Convex environment variable",
    );
  }
  if (secret !== process.env.CONVEX_AUTH_ADAPTER_SECRET) {
    throw new Error("Adapter API called without correct secret value");
  }
}

export const createSession = adapterMutation({
  args: { session: v.object(sessionSchema) },
  handler: async (ctx, { session }) => {
    return await ctx.db.insert("sessions", session);
  },
});

In this example, createSession is a function that inserts a new session into the database. You would need to create similar functions for generateSessionToken, validateSessionToken, and invalidateSession based on your needs.

Please note that this is a simplified example and you might need to adjust it to fit your specific requirements. For a complete guide on creating a custom Convex adapter, please refer to the Convex documentation (https://stack.convex.dev/nextauth-adapter#endpoints).

Note: you can ask me a follow up question by @ mentioning me again :speech_balloon: