Skip to content
Merged
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
9 changes: 7 additions & 2 deletions .env.example
Original file line number Diff line number Diff line change
@@ -1,5 +1,10 @@
# No environment variables are required to run StudyMap locally.
# npm run dev works out of the box with no .env.local file.
# ---------------------------------------------------------------------------
# Supabase (required for auth — sign in / sign up / Google OAuth)
# Get these from: Supabase dashboard > Settings > API
# ---------------------------------------------------------------------------

NEXT_PUBLIC_SUPABASE_URL=https://your-project-ref.supabase.co
NEXT_PUBLIC_SUPABASE_ANON_KEY=your-anon-public-key

# ---------------------------------------------------------------------------
# Analytics (optional)
Expand Down
4 changes: 2 additions & 2 deletions .github/ISSUE_TEMPLATE/config.yml
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
blank_issues_enabled: false
contact_links:
- name: General question or feedback
url: mailto:dhawansanay@gmail.com
url: mailto:studentsuite0@gmail.com
about: Questions and general feedback — from CONTRIBUTING.md.
- name: Security vulnerability
url: mailto:dhawansanay@gmail.com
url: mailto:studentsuite0@gmail.com
about: Report security issues privately — do not open a public issue.
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@

A crowdsourced map of student-important places across the Mumbai Metropolitan Region (Mumbai, Thane, Navi Mumbai). Open source, zero setup, free forever.

**Live:** [study-map-psi.vercel.app](https://study-map-psi.vercel.app)
**Live:** [studymapp.vercel.app](https://studymapp.vercel.app)

---

Expand Down
66 changes: 66 additions & 0 deletions middleware.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,66 @@
import { createServerClient } from "@supabase/ssr";
import { NextResponse, type NextRequest } from "next/server";

export async function middleware(request: NextRequest) {
let supabaseResponse = NextResponse.next({ request });

const supabase = createServerClient(
process.env.NEXT_PUBLIC_SUPABASE_URL!,
process.env.NEXT_PUBLIC_SUPABASE_ANON_KEY!,
{
cookies: {
getAll() {
return request.cookies.getAll();
},
setAll(cookiesToSet) {
cookiesToSet.forEach(({ name, value }) =>
request.cookies.set(name, value),
);
supabaseResponse = NextResponse.next({ request });
cookiesToSet.forEach(({ name, value, options }) =>
supabaseResponse.cookies.set(name, value, options),
);
},
},
},
);

// Refresh session — must not run any code between createServerClient and getUser
const {
data: { user },
} = await supabase.auth.getUser();

const { pathname } = request.nextUrl;

// Public paths that never require auth
const isPublicPath =
pathname.startsWith("/login") || pathname.startsWith("/auth");

if (isPublicPath) {
// Already logged in — send them to the map instead of showing login again
if (user && pathname === "/login") {
return NextResponse.redirect(new URL("/map", request.url));
}
return supabaseResponse;
}

// Everything else requires a session
if (!user) {
const loginUrl = new URL("/login", request.url);
return NextResponse.redirect(loginUrl);
}

return supabaseResponse;
}

export const config = {
matcher: [
/*
* Match all paths except:
* - _next/static (static files)
* - _next/image (image optimisation)
* - favicon, icons, brand, logo assets, manifest
*/
"/((?!_next/static|_next/image|favicon|icons|brand|logo|manifest).*)",
],
};
124 changes: 122 additions & 2 deletions package-lock.json

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

2 changes: 2 additions & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,8 @@
},
"dependencies": {
"@base-ui/react": "^1.5.0",
"@supabase/ssr": "^0.12.0",
"@supabase/supabase-js": "^2.108.2",
"class-variance-authority": "^0.7.1",
"clsx": "^2.1.1",
"leaflet": "^1.9.4",
Expand Down
36 changes: 36 additions & 0 deletions src/app/auth/callback/route.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
import { createServerClient } from "@supabase/ssr";
import { cookies } from "next/headers";
import { NextResponse } from "next/server";

export async function GET(request: Request) {
const { searchParams, origin } = new URL(request.url);
const code = searchParams.get("code");
const next = searchParams.get("next") ?? "/map";

if (code) {
const cookieStore = await cookies();
const supabase = createServerClient(
process.env.NEXT_PUBLIC_SUPABASE_URL!,
process.env.NEXT_PUBLIC_SUPABASE_ANON_KEY!,
{
cookies: {
getAll() {
return cookieStore.getAll();
},
setAll(cookiesToSet) {
cookiesToSet.forEach(({ name, value, options }) =>
cookieStore.set(name, value, options),
);
},
},
},
);

const { error } = await supabase.auth.exchangeCodeForSession(code);
if (!error) {
return NextResponse.redirect(`${origin}${next}`);
}
}

return NextResponse.redirect(`${origin}/login?error=auth_error`);
}
Loading
Loading