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
2 changes: 1 addition & 1 deletion apps/api/src/benchmarks/ratelimit_latency.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -183,5 +183,5 @@ async function createAndTestKeys(
return checks;
}),
);
return results.flatMap((_) => _);
return results.flat();
}
2 changes: 1 addition & 1 deletion apps/dashboard/app/(app)/api/auth/refresh/route.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import { auth } from "@/lib/auth/server";
import { setCookie } from "@/lib/auth/cookies";
import { auth } from "@/lib/auth/server";
import { UNKEY_SESSION_COOKIE } from "@/lib/auth/types";

export async function POST(request: Request) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -63,7 +63,7 @@ export const UpdateKeyExpiration: React.FC<Props> = ({ apiKey }) => {
delayError: 100,
defaultValues: {
keyId: apiKey.id ? apiKey.id : undefined,
enableExpiration: apiKey.expires !== null ? true : false,
enableExpiration: apiKey.expires !== null,
},
});

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -92,7 +92,7 @@ export const Keys: React.FC<Props> = async ({ keyAuthId, apiId }) => {
</Empty>
) : (
Object.entries(keysByExternalId).map(([externalId, ks]) => (
<div className="flex flex-col gap-2">
<div key={externalId} className="flex flex-col gap-2">
<div className="flex items-center gap-1">
{externalId === nullExternalId ? (
<div className="flex items-center justify-between gap-2 text-xs font-medium ph-no-capture">
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -76,7 +76,9 @@ export const UpdateApiName: React.FC<Props> = ({ api }) => {
<div className="flex flex-col space-y-2">
<input type="hidden" name="workspaceId" value={api.workspaceId} />
<input type="hidden" name="apiId" value={api.id} />
<label className="hidden sr-only">Name</label>
<label htmlFor="name" className="hidden sr-only">
Name
</label>
<FormField
control={form.control}
name="name"
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -82,7 +82,9 @@ export const UpdateIpWhitelist: React.FC<Props> = ({ api, workspace }) => {
<div className="flex flex-col space-y-2">
<input type="hidden" name="workspaceId" value={api.workspaceId} />
<input type="hidden" name="apiId" value={api.id} />
<label className="hidden sr-only">Name</label>
<label htmlFor="ipWhitelist" className="hidden sr-only">
IP Whitelist
</label>
<FormField
control={form.control}
name="ipWhitelist"
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -138,7 +138,7 @@ export default async function Page(props: Props) {
</TableHeader>
<TableBody>
{identity.keys.map((key) => (
<TableRow>
<TableRow key={key.id}>
<TableCell className="font-mono">{key.id}</TableCell>
<TableCell className="font-mono text-xs">
{key.meta ? (
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,7 @@ const DisplayPropertyItem = ({
${isFocused ? "ring-2 ring-accent-7" : ""}`}
onClick={onClick}
tabIndex={isFocused ? 0 : -1}
// biome-ignore lint/a11y/useSemanticElements: its okay
role="button"
onKeyDown={(e) => {
if (e.key === "Enter" || e.key === " ") {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -63,7 +63,9 @@ export const UpdateWorkspaceName: React.FC<Props> = ({ workspace }) => {
</CardHeader>
<CardContent>
<div className="flex flex-col space-y-2">
<label className="hidden sr-only">Name</label>
<label htmlFor="name" className="hidden sr-only">
Name
</label>
<FormField
control={form.control}
name="name"
Expand Down
14 changes: 7 additions & 7 deletions apps/dashboard/app/(app)/settings/team/client.tsx
Original file line number Diff line number Diff line change
@@ -1,12 +1,7 @@
"use client";

import { useState, useMemo } from "react";
import Link from "next/link";
import { trpc } from "@/lib/trpc/client";
import { PageHeader } from "@/components/dashboard/page-header";
import { Loading } from "@/components/dashboard/loading";
import { Empty } from "@unkey/ui";
import { Button } from "@unkey/ui";
import { PageHeader } from "@/components/dashboard/page-header";
import {
Select,
SelectContent,
Expand All @@ -15,9 +10,14 @@ import {
SelectTrigger,
SelectValue,
} from "@/components/ui/select";
import { trpc } from "@/lib/trpc/client";
import { Empty } from "@unkey/ui";
import { Button } from "@unkey/ui";
import Link from "next/link";
import { useMemo, useState } from "react";
import { Invitations } from "./invitations";
import { InviteButton } from "./invite";
import { Members } from "./members";
import { Invitations } from "./invitations";

export default function TeamPageClient({ team }: { team: boolean }) {
const { data: user } = trpc.user.getCurrentUser.useQuery();
Expand Down
14 changes: 7 additions & 7 deletions apps/dashboard/app/(app)/settings/team/invitations.tsx
Original file line number Diff line number Diff line change
@@ -1,13 +1,6 @@
"use client";

import { memo } from "react";
import { trpc } from "@/lib/trpc/client";
import { Loading } from "@/components/dashboard/loading";
import { Empty } from "@unkey/ui";
import { toast } from "@/components/ui/toaster";
import { Button } from "@unkey/ui";
import { InviteButton } from "./invite";
import { StatusBadge } from "./status-badge";
import {
Table,
TableBody,
Expand All @@ -16,7 +9,14 @@ import {
TableHeader,
TableRow,
} from "@/components/ui/table";
import { toast } from "@/components/ui/toaster";
import type { Organization, User } from "@/lib/auth/types";
import { trpc } from "@/lib/trpc/client";
import { Empty } from "@unkey/ui";
import { Button } from "@unkey/ui";
import { memo } from "react";
import { InviteButton } from "./invite";
import { StatusBadge } from "./status-badge";

type InvitationsProps = {
user: User | null;
Expand Down
4 changes: 2 additions & 2 deletions apps/dashboard/app/(app)/settings/team/invite.tsx
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
"use client";
import { DialogContainer } from "@/components/dialog-container";
import {
Form,
FormControl,
Expand All @@ -18,15 +19,14 @@ import {
} from "@/components/ui/select";
import { toast } from "@/components/ui/toaster";
import type { Organization, User } from "@/lib/auth/types";
import { trpc } from "@/lib/trpc/client";
import { zodResolver } from "@hookform/resolvers/zod";
import { Button } from "@unkey/ui";
import { Plus } from "lucide-react";
import type React from "react";
import { useState } from "react";
import { useForm } from "react-hook-form";
import { z } from "zod";
import { DialogContainer } from "@/components/dialog-container";
import { trpc } from "@/lib/trpc/client";

const formSchema = z.object({
email: z.string().email(),
Expand Down
18 changes: 9 additions & 9 deletions apps/dashboard/app/(app)/settings/team/members.tsx
Original file line number Diff line number Diff line change
@@ -1,14 +1,8 @@
"use client";

import { memo } from "react";
import { trpc } from "@/lib/trpc/client";
import { Loading } from "@/components/dashboard/loading";
import { Empty } from "@unkey/ui";
import { toast } from "@/components/ui/toaster";
import Confirm from "@/components/dashboard/confirm";
import { Button } from "@unkey/ui";
import { InviteButton } from "./invite";
import { RoleSwitcher } from "./role-switcher";
import { Loading } from "@/components/dashboard/loading";
import { Avatar, AvatarFallback, AvatarImage } from "@/components/ui/avatar";
import {
Table,
TableBody,
Expand All @@ -17,8 +11,14 @@ import {
TableHeader,
TableRow,
} from "@/components/ui/table";
import { Avatar, AvatarFallback, AvatarImage } from "@/components/ui/avatar";
import { toast } from "@/components/ui/toaster";
import type { Membership, Organization, User } from "@/lib/auth/types";
import { trpc } from "@/lib/trpc/client";
import { Empty } from "@unkey/ui";
import { Button } from "@unkey/ui";
import { memo } from "react";
import { InviteButton } from "./invite";
import { RoleSwitcher } from "./role-switcher";

type MembersProps = {
organization: Organization | null;
Expand Down
4 changes: 2 additions & 2 deletions apps/dashboard/app/(app)/settings/team/page.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -3,9 +3,9 @@ import { Navigation } from "@/components/navigation/navigation";
import { PageContent } from "@/components/page-content";
import { getOrgId } from "@/lib/auth";
import { db } from "@/lib/db";
import TeamPageClient from "./client";
import { navigation } from "../constants";
import { Gear } from "@unkey/icons";
import { navigation } from "../constants";
import TeamPageClient from "./client";

export const revalidate = 0;

Expand Down
6 changes: 3 additions & 3 deletions apps/dashboard/app/(app)/settings/team/role-switcher.tsx
Original file line number Diff line number Diff line change
@@ -1,9 +1,6 @@
"use client";

import { memo, useState } from "react";
import { trpc } from "@/lib/trpc/client";
import { Loading } from "@/components/dashboard/loading";
import { toast } from "@/components/ui/toaster";
import {
Select,
SelectContent,
Expand All @@ -12,7 +9,10 @@ import {
SelectTrigger,
SelectValue,
} from "@/components/ui/select";
import { toast } from "@/components/ui/toaster";
import type { Membership, Organization, User } from "@/lib/auth/types";
import { trpc } from "@/lib/trpc/client";
import { memo, useState } from "react";

type RoleSwitcherProps = {
member: { id: string; role: string };
Expand Down
2 changes: 1 addition & 1 deletion apps/dashboard/app/(app)/settings/team/status-badge.tsx
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
"use client";

import { memo } from "react";
import { Badge } from "@/components/ui/badge";
import { memo } from "react";

type StatusBadgeProps = {
status: "pending" | "accepted" | "revoked" | "expired";
Expand Down
21 changes: 10 additions & 11 deletions apps/dashboard/app/auth/actions.ts
Original file line number Diff line number Diff line change
@@ -1,21 +1,20 @@
"use server";

import { setCookies, getCookie, deleteCookie, SetSessionCookie } from "@/lib/auth/cookies";
import { SetSessionCookie, deleteCookie, getCookie, setCookies } from "@/lib/auth/cookies";
import { auth } from "@/lib/auth/server";
import {
AuthErrorCode,
AuthErrorResponse,
EmailAuthResult,
errorMessages,
NavigationResponse,
OAuthResult,
type AuthErrorResponse,
type EmailAuthResult,
type NavigationResponse,
type OAuthResult,
PENDING_SESSION_COOKIE,
SignInViaOAuthOptions,
UNKEY_SESSION_COOKIE,
UserData,
VerificationResult,
type SignInViaOAuthOptions,
type UserData,
type VerificationResult,
errorMessages,
} from "@/lib/auth/types";
import { requireEmailMatch, requireAuth } from "@/lib/auth/utils";
import { requireEmailMatch } from "@/lib/auth/utils";
import { cookies } from "next/headers";
import { redirect } from "next/navigation";

Expand Down
2 changes: 1 addition & 1 deletion apps/dashboard/app/auth/context/signup-context.tsx
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
"use client";

import { createContext, useContext, useState } from "react";
import type { UserData } from "@/lib/auth/types";
import { createContext, useContext, useState } from "react";

interface SignUpContextType {
userData: UserData;
Expand Down
8 changes: 4 additions & 4 deletions apps/dashboard/app/auth/hooks/useSignIn.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,3 @@
import { useSearchParams } from "next/navigation";
import { useContext, useEffect, useState } from "react";
import { resendAuthCode, signInViaEmail, verifyAuthCode } from "../actions";
import { SignInContext } from "../context/signin-context";
import { getCookie } from "@/lib/auth/cookies";
import {
AuthErrorCode,
Expand All @@ -13,6 +9,10 @@ import {
type VerificationResult,
errorMessages,
} from "@/lib/auth/types";
import { useSearchParams } from "next/navigation";
import { useContext, useEffect, useState } from "react";
import { resendAuthCode, signInViaEmail, verifyAuthCode } from "../actions";
import { SignInContext } from "../context/signin-context";

function isAuthErrorResponse(result: VerificationResult): result is AuthErrorResponse {
return !result.success && "message" in result;
Expand Down
2 changes: 1 addition & 1 deletion apps/dashboard/app/auth/hooks/useSignUp.ts
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
"use client";

import type { UserData } from "@/lib/auth/types";
import { resendAuthCode, signUpViaEmail, verifyAuthCode, verifyEmail } from "../actions";
import { useSignUpContext } from "../context/signup-context";
import type { UserData } from "@/lib/auth/types";

export function useSignUp() {
const { userData, updateUserData, clearUserData } = useSignUpContext();
Expand Down
24 changes: 10 additions & 14 deletions apps/dashboard/app/auth/join/route.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import { NextRequest, NextResponse } from "next/server";
import { auth } from "@/lib/auth/server";
import { type NextRequest, NextResponse } from "next/server";
import { switchOrg } from "../actions";

export async function GET(request: NextRequest) {
Expand All @@ -13,8 +13,6 @@ export async function GET(request: NextRequest) {
return NextResponse.redirect(DASHBOARD_URL); // middleware will pickup if they are not authenticated and redirect to login
}

console.log("join page");

const user = await auth.getCurrentUser();
// exchange token for invitation
const invitation = await auth.getInvitation(invitationToken);
Expand Down Expand Up @@ -45,19 +43,17 @@ export async function GET(request: NextRequest) {
}

// if they are not authenticated
else {
const existingUser = await auth.findUser(invitationEmail);

if (existingUser) {
SIGN_IN_URL.searchParams.set("invitation_token", invitationToken);
SIGN_IN_URL.searchParams.set("email", invitationEmail);
const existingUser = await auth.findUser(invitationEmail);

return NextResponse.redirect(SIGN_IN_URL);
} else {
SIGN_UP_URL.searchParams.set("invitation_token", invitationToken);
SIGN_UP_URL.searchParams.set("email", invitationEmail);
if (existingUser) {
SIGN_IN_URL.searchParams.set("invitation_token", invitationToken);
SIGN_IN_URL.searchParams.set("email", invitationEmail);

return NextResponse.redirect(SIGN_UP_URL);
}
return NextResponse.redirect(SIGN_IN_URL);
}
SIGN_UP_URL.searchParams.set("invitation_token", invitationToken);
SIGN_UP_URL.searchParams.set("email", invitationEmail);

return NextResponse.redirect(SIGN_UP_URL);
}
16 changes: 9 additions & 7 deletions apps/dashboard/app/auth/sign-in/[[...sign-in]]/page.tsx
Original file line number Diff line number Diff line change
@@ -1,19 +1,19 @@
"use client";

import { Loading } from "@/components/dashboard/loading";
import { FadeIn } from "@/components/landing/fade-in";
import { SignInProvider } from "../../context/signin-context";
import { useSignIn } from "../../hooks";
import { MoveRight } from "lucide-react";
import Link from "next/link";
import { useSearchParams } from "next/navigation";
import { useEffect, useRef, useState } from "react";
import { ErrorBanner, WarnBanner } from "../../banners";
import { SignInProvider } from "../../context/signin-context";
import { useSignIn } from "../../hooks";
import { EmailCode } from "../email-code";
import { EmailSignIn } from "../email-signin";
import { EmailVerify } from "../email-verify";
import { OAuthSignIn } from "../oauth-signin";
import { OrgSelector } from "../org-selector";
import { useSearchParams } from "next/navigation";
import { EmailVerify } from "../email-verify";
import { useEffect, useRef, useState } from "react";
import { Loading } from "@/components/dashboard/loading";

function SignInContent() {
const { isVerifying, accountNotFound, error, email, hasPendingAuth, orgs, handleSignInViaEmail } =
Expand All @@ -38,7 +38,9 @@ function SignInContent() {
// Handle auto sign-in with invitation token and email
useEffect(() => {
// Only run this effect on the client side after hydration
if (!clientReady) return;
if (!clientReady) {
return;
}

const attemptAutoSignIn = async () => {
// Only proceed if we have required data, aren't in other auth states, and haven't attempted sign-in yet
Expand Down
Loading
Loading