Skip to content

Commit

Permalink
feat: creates auth package
Browse files Browse the repository at this point in the history
  • Loading branch information
ixahmedxi committed Jan 30, 2024
1 parent e4352af commit 6df1590
Show file tree
Hide file tree
Showing 34 changed files with 1,276 additions and 154 deletions.
4 changes: 2 additions & 2 deletions apps/web/next.config.js
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
import './src/env.mjs';
import './src/env.js';

/** @type {import('next').NextConfig} */
const nextConfig = {
transpilePackages: ['@orbitkit/db'],
transpilePackages: ['@orbitkit/db', '@orbitkit/auth'],
};

export default nextConfig;
3 changes: 2 additions & 1 deletion apps/web/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@
"typecheck": "tsc --noEmit --tsBuildInfoFile .tsbuildinfo"
},
"dependencies": {
"@orbitkit/auth": "workspace:^",
"@orbitkit/db": "workspace:^",
"@orbitkit/ui": "workspace:^",
"@t3-oss/env-nextjs": "^0.8.0",
Expand All @@ -27,7 +28,7 @@
"devDependencies": {
"@orbitkit/tailwind": "workspace:^",
"@orbitkit/tsconfig": "workspace:^",
"@types/node": "^20.11.7",
"@types/node": "^20.11.10",
"@types/react": "^18.2.48",
"@types/react-dom": "^18.2.18",
"autoprefixer": "^10.4.17",
Expand Down
3 changes: 3 additions & 0 deletions apps/web/src/app/(auth)/login/github/callback/route.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
import { validateGithubCallback } from '@orbitkit/auth/providers/github';

export { validateGithubCallback as GET };
3 changes: 3 additions & 0 deletions apps/web/src/app/(auth)/login/github/route.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
import { createGithubAuthorizationURL } from '@orbitkit/auth/providers/github';

export { createGithubAuthorizationURL as GET };
10 changes: 10 additions & 0 deletions apps/web/src/app/(auth)/login/page.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
import Link from 'next/link';

export default function Page() {
return (
<>
<h1>Sign in</h1>
<Link href="/login/github">Sign in with Github</Link>
</>
);
}
4 changes: 2 additions & 2 deletions apps/web/src/app/layout.tsx
Original file line number Diff line number Diff line change
@@ -1,10 +1,10 @@
import './globals.css';

import type { Metadata } from 'next';

import { GeistMono } from 'geist/font/mono';
import { GeistSans } from 'geist/font/sans';

import './globals.css';

import { Providers } from './providers';

export const metadata: Metadata = {
Expand Down
17 changes: 15 additions & 2 deletions apps/web/src/app/page.tsx
Original file line number Diff line number Diff line change
@@ -1,13 +1,23 @@
import { ThemeSwitcher } from '@/components/ThemeSwitcher';
import { redirect } from 'next/navigation';

import { getSession } from '@orbitkit/auth';
import { logout } from '@orbitkit/auth/actions/logout';
import { db } from '@orbitkit/db';
import { Avatar, AvatarFallback, AvatarImage } from '@orbitkit/ui/avatar';

import { ThemeSwitcher } from '@/components/ThemeSwitcher';

export default async function Home() {
const { user } = await getSession();
if (!user) {
return redirect('/login');
}

const users = await db.query.userTable.findMany();

return (
<main className="container mx-auto">
<h1>Hello World</h1>
<h1>Hi, {user.username}!</h1>
{JSON.stringify(users)}
<ThemeSwitcher />
<Avatar>
Expand All @@ -18,6 +28,9 @@ export default async function Home() {
<AvatarImage src="https://github.com/shadcnnnnn.png" alt="@shadcn" />
<AvatarFallback>CN</AvatarFallback>
</Avatar>
<form action={logout}>
<button>Sign out</button>
</form>
</main>
);
}
1 change: 0 additions & 1 deletion apps/web/src/app/providers.tsx
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
'use client';

import { type FC, type PropsWithChildren } from 'react';

import { ThemeProvider as NextThemesProvider } from 'next-themes';

export const Providers: FC<PropsWithChildren> = ({ children }) => {
Expand Down
1 change: 0 additions & 1 deletion apps/web/src/components/ThemeSwitcher.tsx
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
'use client';

import { useEffect, useState } from 'react';

import { useTheme } from 'next-themes';

export const ThemeSwitcher = () => {
Expand Down
6 changes: 4 additions & 2 deletions apps/web/src/env.mjs → apps/web/src/env.js
Original file line number Diff line number Diff line change
@@ -1,9 +1,11 @@
import { env as dbEnv } from '@orbitkit/db/env';
import { createEnv } from '@t3-oss/env-nextjs';
import { vercel } from '@t3-oss/env-nextjs/presets';

import { env as authEnv } from '@orbitkit/auth/env';
import { env as dbEnv } from '@orbitkit/db/env';

export const env = createEnv({
extends: [dbEnv, vercel],
extends: [dbEnv, authEnv, vercel],
server: {},
client: {},
runtimeEnv: {},
Expand Down
6 changes: 3 additions & 3 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@
"husky": "^9.0.6",
"lint-staged": "^15.2.0",
"markdownlint": "^0.33.0",
"markdownlint-cli": "^0.38.0",
"markdownlint-cli": "^0.39.0",
"prettier": "^3.2.4",
"prettier-plugin-curly": "^0.1.3",
"prettier-plugin-jsdoc": "^1.3.0",
Expand All @@ -41,9 +41,9 @@
"turbo": "^1.11.3",
"typescript": "^5.3.3"
},
"packageManager": "pnpm@8.14.1",
"packageManager": "pnpm@8.15.0",
"volta": {
"node": "20.11.0",
"pnpm": "8.14.1"
"pnpm": "8.15.0"
}
}
7 changes: 7 additions & 0 deletions packages/auth/.eslintrc.cjs
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
/** @type {import('eslint').Linter.Config} */
const config = {
root: true,
extends: ['orbitkit/base'],
};

module.exports = config;
39 changes: 39 additions & 0 deletions packages/auth/package.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
{
"name": "@orbitkit/auth",
"version": "0.1.0",
"private": true,
"description": "Auth package for OrbitKit",
"license": "MIT",
"author": "OrbitKit",
"sideEffects": false,
"type": "module",
"exports": {
".": "./src/index.ts",
"./env": "./src/env.js",
"./providers/github": "./src/providers/github.ts",
"./actions/logout": "./src/actions/logout.ts"
},
"scripts": {
"lint": "eslint . --cache --max-warnings 0",
"typecheck": "tsc --noEmit --tsBuildInfoFile .tsbuildinfo"
},
"dependencies": {
"@lucia-auth/adapter-drizzle": "^1.0.0",
"@orbitkit/db": "workspace:^",
"@t3-oss/env-core": "^0.8.0",
"@types/react-dom": "^18.2.18",
"arctic": "^1.1.0",
"lucia": "^3.0.1",
"next": "14.1.0",
"oslo": "^1.0.3",
"react": "^18.2.0",
"react-dom": "^18.2.0",
"zod": "^3.22.4"
},
"devDependencies": {
"@orbitkit/tsconfig": "workspace:^",
"@types/node": "^20.11.10",
"@types/react": "^18.2.48",
"eslint-config-orbitkit": "workspace:^"
}
}
28 changes: 28 additions & 0 deletions packages/auth/src/actions/logout.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
'use server';

import { cookies } from 'next/headers';
import { redirect } from 'next/navigation';

import { getSession } from '../getSession';
import { lucia } from '../lucia';

export async function logout() {
const { session } = await getSession();
if (!session) {
return {
error: 'Unauthorized',
};
}

await lucia.invalidateSession(session.id);

const sessionCookie = lucia.createBlankSessionCookie();

cookies().set(
sessionCookie.name,
sessionCookie.value,
sessionCookie.attributes,
);

return redirect('/login');
}
18 changes: 18 additions & 0 deletions packages/auth/src/env.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
import { createEnv } from '@t3-oss/env-core';
import { vercel } from '@t3-oss/env-core/presets';
import { z } from 'zod';

export const env = createEnv({
extends: [vercel],
server: {
NODE_ENV: z.enum(['development', 'test', 'production']).optional(),
GITHUB_CLIENT_ID: z.string(),
GITHUB_CLIENT_SECRET: z.string(),
},
runtimeEnv: {
NODE_ENV: process.env['NODE_ENV'],
GITHUB_CLIENT_ID: process.env['GITHUB_CLIENT_ID'],
GITHUB_CLIENT_SECRET: process.env['GITHUB_CLIENT_SECRET'],
},
emptyStringAsUndefined: true,
});
41 changes: 41 additions & 0 deletions packages/auth/src/getSession.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
import { cache } from 'react';
import { cookies } from 'next/headers';

import { type Session, type User } from 'lucia';

import { lucia } from './lucia';

export const getSession = cache(
async (): Promise<
{ user: User; session: Session } | { user: null; session: null }
> => {
const sessionId = cookies().get(lucia.sessionCookieName)?.value ?? null;
if (!sessionId) {
return {
user: null,
session: null,
};
}

const result = await lucia.validateSession(sessionId);
try {
if (result.session && result.session.fresh) {
const sessionCookie = lucia.createSessionCookie(result.session.id);
cookies().set(
sessionCookie.name,
sessionCookie.value,
sessionCookie.attributes,
);
}
if (!result.session) {
const sessionCookie = lucia.createBlankSessionCookie();
cookies().set(
sessionCookie.name,
sessionCookie.value,
sessionCookie.attributes,
);
}
} catch {}
return result;
},
);
2 changes: 2 additions & 0 deletions packages/auth/src/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
export * from './lucia';
export * from './getSession';
33 changes: 33 additions & 0 deletions packages/auth/src/lucia.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
import { DrizzlePostgreSQLAdapter } from '@lucia-auth/adapter-drizzle';
import { Lucia } from 'lucia';

import { db } from '@orbitkit/db';
import { sessionTable, userTable } from '@orbitkit/db/schema';

import { env } from './env.js';

const adapter = new DrizzlePostgreSQLAdapter(db, sessionTable, userTable);

export const lucia = new Lucia(adapter, {
sessionCookie: {
attributes: {
secure: env.NODE_ENV === 'production',
},
},
getUserAttributes: (attributes) => {
return {
githubId: attributes.github_id,
username: attributes.username,
};
},
});

declare module 'lucia' {
interface Register {
Lucia: typeof lucia;
DatabaseUserAttributes: {
github_id: string;
username: string;
};
}
}
Loading

0 comments on commit 6df1590

Please sign in to comment.