Skip to content

Commit

Permalink
Use OAuth2Strategy instead of GitHubStrategy
Browse files Browse the repository at this point in the history
  • Loading branch information
sergiodxa committed May 29, 2024
1 parent ac8fad9 commit f671408
Show file tree
Hide file tree
Showing 3 changed files with 58 additions and 28 deletions.
57 changes: 41 additions & 16 deletions app/modules/auth.server.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ import type { User } from "./session.server";
import { createCookieSessionStorage } from "@remix-run/cloudflare";
import { and, eq } from "drizzle-orm";
import { Authenticator } from "remix-auth";
import { GitHubStrategy } from "remix-auth-github";
import { OAuth2Strategy } from "remix-auth-oauth2";
import { z } from "zod";

import { Tables, database } from "~/services/db.server";
Expand All @@ -16,7 +16,7 @@ export class Auth {

public authenticate: Authenticator<User>["authenticate"];

constructor(context: AppLoadContext) {
constructor(url: URL, context: AppLoadContext) {
this.sessionStorage = createCookieSessionStorage({
cookie: {
name: "sdx:auth",
Expand All @@ -38,13 +38,37 @@ export class Auth {
let gh = new GitHub(context.env.GH_APP_ID, context.env.GH_APP_PEM);

this.authenticator.use(
new GitHubStrategy(
new OAuth2Strategy(
{
clientID: context.env.GITHUB_CLIENT_ID,
clientId: context.env.GITHUB_CLIENT_ID,
clientSecret: context.env.GITHUB_CLIENT_SECRET,
callbackURL: "/auth/github/callback",
redirectURI: new URL("/auth/github/callback", url),
authorizationEndpoint: new URL(
"https://github.com/login/oauth/authorize",
),
tokenEndpoint: new URL("https://github.com/login/oauth/access_token"),
scopes: ["read:user", "user:email"],
},
async ({ profile }) => {
async ({ tokens }) => {
let response = await fetch("https://api.github.com/user", {
headers: {
Accept: "application/vnd.github.v3+json",
Authorization: `token ${tokens.access_token}`,
"User-Agent": "Remix Auth",
},
});

let profile = await z
.object({
node_id: z.string(),
email: z.string().email(),
login: z.string(),
name: z.string(),
avatar_url: z.string().url(),
})
.promise()
.parse(response.json());

let connection = await db.query.connections.findFirst({
with: {
user: {
Expand All @@ -56,7 +80,7 @@ export class Auth {
},
where: and(
eq(Tables.connections.providerName, "github"),
eq(Tables.connections.providerId, profile._json.node_id),
eq(Tables.connections.providerId, profile.node_id),
),
});

Expand All @@ -65,19 +89,19 @@ export class Auth {
if (user) {
return {
...user,
githubId: profile._json.node_id,
isSponsor: await gh.isSponsoringMe(profile._json.node_id),
githubId: profile.node_id,
isSponsor: await gh.isSponsoringMe(profile.node_id),
};
}

let result = await db
.insert(Tables.users)
.values({
role: "guess",
email: profile._json.email,
avatar: z.string().url().parse(profile._json.avatar_url),
username: profile._json.login,
displayName: profile._json.name,
email: profile.email,
avatar: z.string().url().parse(profile.avatar_url),
username: profile.login,
displayName: profile.name,
})
.returning()
.onConflictDoNothing({ target: Tables.users.email });
Expand All @@ -88,7 +112,7 @@ export class Auth {
await db.insert(Tables.connections).values({
userId: user.id,
providerName: "github",
providerId: profile._json.node_id,
providerId: profile.node_id,
});

return {
Expand All @@ -98,11 +122,12 @@ export class Auth {
avatar: user.avatar,
username: user.username,
displayName: user.displayName,
githubId: profile._json.node_id,
isSponsor: await gh.isSponsoringMe(profile._json.node_id),
githubId: profile.node_id,
isSponsor: await gh.isSponsoringMe(profile.node_id),
};
},
),
"github",
);

this.authenticate = this.authenticator.authenticate.bind(
Expand Down
2 changes: 1 addition & 1 deletion app/routes/_.auth.login.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ export async function loader({ request, context }: LoaderFunctionArgs) {
}

export async function action({ request, context }: ActionFunctionArgs) {
let auth = new Auth(context);
let auth = new Auth(new URL(request.url), context);

return await auth.authenticate("github", request, {
successRedirect: "/auth/github/callback",
Expand Down
27 changes: 16 additions & 11 deletions app/routes/auth.$provider.callback.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,23 +5,28 @@ import { Auth } from "~/modules/auth.server";
import { SessionStorage } from "~/modules/session.server";

export async function loader({ request, params, context }: LoaderFunctionArgs) {
let provider = z.enum(["github"]).parse(params.provider);
try {
let provider = z.enum(["github"]).parse(params.provider);

let auth = new Auth(context);
let auth = new Auth(new URL(request.url), context);

let user = await auth.authenticate(provider, request);
let user = await auth.authenticate(provider, request);

if (!user) throw redirect("/auth/login");
if (!user) throw redirect("/auth/login");

let sessionStorage = new SessionStorage(context);
let sessionStorage = new SessionStorage(context);

let session = await sessionStorage.read(request.headers.get("cookie"));
session.set("user", user);
let session = await sessionStorage.read(request.headers.get("cookie"));
session.set("user", user);

let headers = new Headers();
let headers = new Headers();

headers.append("set-cookie", await sessionStorage.commit(session));
headers.append("set-cookie", await auth.clear(request));
headers.append("set-cookie", await sessionStorage.commit(session));
headers.append("set-cookie", await auth.clear(request));

throw redirect("/", { headers });
throw redirect("/", { headers });
} catch (error) {
console.error(error);
throw error;
}
}

0 comments on commit f671408

Please sign in to comment.