Skip to content

Commit

Permalink
auth middleware (init)
Browse files Browse the repository at this point in the history
  • Loading branch information
ciscorn committed Sep 6, 2024
1 parent 5bc7d48 commit f8ee6ae
Show file tree
Hide file tree
Showing 7 changed files with 106 additions and 60 deletions.
69 changes: 29 additions & 40 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

7 changes: 3 additions & 4 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -21,14 +21,15 @@
"@stripe/stripe-js": "^4.4.0",
"@sveltejs/adapter-cloudflare": "^4.7.2",
"@sveltejs/kit": "^2.0.0",
"@sveltejs/vite-plugin-svelte": "^3.0.0",
"@sveltejs/vite-plugin-svelte": "^4.0.0-next.6",
"@types/eslint": "^8.56.7",
"eslint": "^9.0.0",
"eslint-config-prettier": "^9.1.0",
"eslint-plugin-svelte": "^2.36.0",
"firebase": "^10.12.3",
"firebase-auth-cloudflare-workers-x509": "^2.0.5",
"globals": "^15.0.0",
"hono": "^4.5.11",
"prettier": "^3.1.1",
"prettier-plugin-svelte": "^3.1.2",
"stripe": "^16.7.0",
Expand All @@ -48,9 +49,7 @@
}
},
"type": "module",
"dependencies": {
"hono": "^4.5.11"
},
"dependencies": {},
"volta": {
"node": "20.17.0"
}
Expand Down
49 changes: 49 additions & 0 deletions src/api/auth.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
import type { Context } from 'hono';
import { getCookie } from 'hono/cookie';
import { createMiddleware } from 'hono/factory';
import {
Auth,
ServiceAccountCredential,
WorkersKVStoreSingle
} from 'firebase-auth-cloudflare-workers-x509';
import { GOOGLE_SERVICE_ACCOUNT_KEY } from '$env/static/private';
import { HTTPException } from 'hono/http-exception';

type CurrentUser = {
uid: string;
name: string;
};

export interface AuthVariables {
currentUser?: CurrentUser;
}

export const authMiddleware = createMiddleware(async (c, next) => {
const sessionCookie = getCookie(c, 'session');
if (sessionCookie) {
const keys = WorkersKVStoreSingle.getOrInitialize('pubkeys', c.env.KV);
const auth = Auth.getOrInitialize(
'fukada-delete-me',
keys,
new ServiceAccountCredential(GOOGLE_SERVICE_ACCOUNT_KEY)
);
try {
const idToken = await auth.verifySessionCookie(sessionCookie);
c.set('currentUser', {
uid: idToken.uid,
name: idToken.name
});
} catch {
// ignore
}
}
await next();
});

export function ensureUser(c: Context) {
const currentUser = c.get('currentUser') as CurrentUser;
if (!currentUser) {
throw new HTTPException(401, { message: 'Not authorized' });
}
return currentUser;
}
24 changes: 14 additions & 10 deletions src/api/index.ts
Original file line number Diff line number Diff line change
@@ -1,20 +1,24 @@
import { Hono } from 'hono';
import { authMiddleware, ensureUser, type AuthVariables } from './auth';

export type Post = {
title: string;
author: string;
};

const app = new Hono().get('/api/posts', async (c) => {
const posts: Post[] = [];
for (let i = 0; i < 20; i++) {
posts.push({
title: '素晴しい記事',
author: '名無し'
});
}
return c.json(posts);
});
const app = new Hono<{ Bindings: Env; Variables: AuthVariables }>()
.use(authMiddleware)
.get('/api/posts', async (c) => {
const currentUser = ensureUser(c);
const posts: Post[] = [];
for (let i = 0; i < 20; i++) {
posts.push({
title: '素晴しい記事',
author: currentUser.name
});
}
return c.json(posts);
});

export default app;

Expand Down
8 changes: 5 additions & 3 deletions src/app.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,10 @@ import type { BasicPrivateUserInfo } from './lib/user';

// for information about these interfaces
declare global {
interface Env {
KV: KVNamespace;
}

namespace App {
// interface Error {}
interface Locals {
Expand All @@ -14,9 +18,7 @@ declare global {
}
// interface PageState {}
interface Platform {
env?: {
KV: KVNamespace;
};
env?: EnV;
}
}
}
Expand Down
3 changes: 1 addition & 2 deletions src/routes/session/+server.ts
Original file line number Diff line number Diff line change
Expand Up @@ -12,8 +12,7 @@ export const POST = async ({ request, cookies, platform }) => {
return request
.json()
.then(async (data) => {
const idToken = data.idToken;

const idToken = (data as { idToken?: string }).idToken;
const days = 14; // 5 min - 14 days
if (typeof idToken === 'string') {
const cookie = await createSessionCookie(keys, idToken, days);
Expand Down
6 changes: 5 additions & 1 deletion tsconfig.json
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,11 @@
"skipLibCheck": true,
"sourceMap": true,
"strict": true,
"moduleResolution": "bundler"
"moduleResolution": "bundler",
"types": [
"@cloudflare/workers-types",
"@cloudflare/workers-types/experimental"
]
}
// Path aliases are handled by https://kit.svelte.dev/docs/configuration#alias
// except $lib which is handled by https://kit.svelte.dev/docs/configuration#files
Expand Down

0 comments on commit f8ee6ae

Please sign in to comment.