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
4 changes: 2 additions & 2 deletions .env.example
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
NEXT_PUBLIC_APP_URL=http://localhost:3000
NEXT_PUBLIC_BACKEND_URL=http://localhost:8787
VITE_PUBLIC_APP_URL=http://localhost:3000
VITE_PUBLIC_BACKEND_URL=http://localhost:8787

DATABASE_URL="postgresql://postgres:postgres@localhost:5432/zerodotemail"

Expand Down
34 changes: 17 additions & 17 deletions .github/CONTRIBUTING.md
Original file line number Diff line number Diff line change
Expand Up @@ -29,24 +29,24 @@ Thank you for your interest in contributing to 0.email! We're excited to have yo
- Clone your fork locally: `git clone https://github.com/YOUR-USERNAME/Zero.git`

2. **Set Up Development Environment**
- Install [Bun](https://bun.sh)
- Clone the repository and install dependencies: `bun install`
- Start the database locally: `bun docker:db:up`
- Install [pnpm](https://pnpm.io)
- Clone the repository and install dependencies: `pnpm install`
- Start the database locally: `pnpm docker:up`
- Copy `.env.example` to `.env` in project root
- Setup cloudflare with `bun run cf-install`, you will need to run this everytime there is a `.env` change
- Setup cloudflare with `pnpm run cf-install`, you will need to run this everytime there is a `.env` change
- Set up your Google OAuth credentials (see [README.md](../README.md))
- Initialize the database: `bun db:push`
- Initialize the database: `pnpm db:push`

## Development Workflow

1. **Start the Development Environment**

```bash
# Start database locally
bun docker:db:up
pnpm docker:up

# Start the development server
bun dev
pnpm dev
```

2. **Create a New Branch**
Expand Down Expand Up @@ -90,8 +90,9 @@ Thank you for your interest in contributing to 0.email! We're excited to have yo
git fetch upstream
git merge upstream/staging
```
>[!IMPORTANT]
>Remember to make `staging` branch as your base branch.

> [!IMPORTANT]
> Remember to make `staging` branch as your base branch.

7. **Push to Your Fork**

Expand All @@ -104,10 +105,9 @@ Thank you for your interest in contributing to 0.email! We're excited to have yo
- Fill out the PR template completely
- Link any relevant issues
- Add screenshots for UI changes

>[!IMPORTANT]
>Remember to make your pull request into the `staging` branch


> [!IMPORTANT]
> Remember to make your pull request into the `staging` branch

## Database Management

Expand All @@ -121,16 +121,16 @@ Zero uses PostgreSQL with Drizzle ORM. Here's how to work with it:

```bash
# Apply schema changes to development database
bun db:push
pnpm db:push

# Create migration files after schema changes
bun db:generate
pnpm db:generate

# Apply migrations (for production)
bun db:migrate
pnpm db:migrate

# View and edit data with Drizzle Studio
bun db:studio
pnpm db:studio
```

3. **Database Connection**
Expand Down
10 changes: 3 additions & 7 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -15,15 +15,11 @@ jobs:
- name: Checkout Code 🛎
uses: actions/checkout@v4

- name: Setup Bun 🌟
uses: oven-sh/setup-bun@v1
with:
bun-version: latest
- name: Setup pnpm 🌟
uses: pnpm/action-setup@v4

- name: Setup Node 📦
uses: actions/setup-node@v4
with:
node-version: latest

- name: Install dependencies 📦
run: bun install
run: pnpm install
10 changes: 3 additions & 7 deletions .github/workflows/main.yml
Original file line number Diff line number Diff line change
Expand Up @@ -27,18 +27,14 @@ jobs:
- name: Checkout Code 🛎
uses: actions/checkout@v4

- name: Setup Bun 🌟
uses: oven-sh/setup-bun@v1
with:
bun-version: latest
- name: Setup pnpm 🌟
uses: pnpm/action-setup@v4

- name: Setup Node 📦
uses: actions/setup-node@v4
with:
node-version: latest

- name: Install dependencies 📦
run: bun install
run: pnpm install

- name: Run Lingo.dev Localization 🌐
if: ${{ !inputs.skip_localization }}
Expand Down
7 changes: 3 additions & 4 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -1,9 +1,7 @@
# See https://help.github.com/articles/ignoring-files/ for more about ignoring files.

# dependencies
/node_modules
/apps/*/node_modules
/packages/*/node_modules
node_modules
/.pnp
.pnp.*
.yarn/*
Expand Down Expand Up @@ -53,4 +51,5 @@ apps/mail/scripts.ts
.wrangler
worker-configuration.d.ts

.dev.vars.*
.dev.vars.*
.react-router
1 change: 1 addition & 0 deletions .nvmrc
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
v22
60 changes: 14 additions & 46 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,7 @@ Zero is built with modern and reliable technologies:
**Required Versions:**

- [Node.js](https://nodejs.org/en/download) (v18 or higher)
- [Bun](https://bun.sh) (v1.2 or higher)
- [pnpm](https://pnpm.io) (v10 or higher)
- [Docker](https://docs.docker.com/engine/install/) (v20 or higher)

Before running the application, you'll need to set up services and configure environment variables. For more details on environment variables, see the [Environment Variables](#environment-variables) section.
Expand All @@ -67,10 +67,10 @@ You can set up Zero in two ways:
cd Zero

# Install dependencies
bun install
pnpm install

# Start database locally
bun docker:db:up
pnpm docker:up
```

2. **Set Up Environment**
Expand All @@ -80,53 +80,21 @@ You can set up Zero in two ways:
cp .env.example .env
```
- Configure your environment variables (see below)
- Setup cloudflare with `bun run cf-install`, you will need to run this everytime there is a `.env` change
- Start the database with the provided docker compose setup: `bun docker:db:up`
- Initialize the database: `bun db:push`
- Setup cloudflare with `pnpm run cf-install`, you will need to run this everytime there is a `.env` change
- Start the database with the provided docker compose setup: `pnpm docker:up`
- Initialize the database: `pnpm db:push`

3. **Start the App**

```bash
bun dev
pnpm dev
```

4. **Open in Browser**

Visit [http://localhost:3000](http://localhost:3000)
</details>

<details>
<summary><b>Option 2: Dev Container Setup (For VS Code Users)</b></summary>

This option uses VS Code's Dev Containers feature to provide a fully configured development environment with all dependencies pre-installed. It's great for ensuring everyone on the team has the same setup.

1. **Prerequisites**

- [Docker](https://docs.docker.com/get-docker/)
- [VS Code](https://code.visualstudio.com/) or compatible editor
- [Dev Containers extension](https://marketplace.visualstudio.com/items?itemName=ms-vscode-remote.remote-containers)

2. **Open in Dev Container**

- Clone the repository: `git clone https://github.com/Mail-0/Zero.git`
- Open the folder in VS Code
- When prompted, click "Reopen in Container" or run the "Dev Containers: Open Folder in Container" command
- VS Code will build and start the dev container (this may take a few minutes the first time)

3. **Access the App**

- The app will be available at [http://localhost:3000](http://localhost:3000)

4. **Troubleshooting**
- If you encounter issues with the container, try rebuilding it using the "Dev Containers: Rebuild Container" command
- For dependency issues inside the container:
`bash
rm -rf node_modules
rm bun.lockb
bun install
`
</details>

### Environment Setup

1. **Better Auth Setup**
Expand Down Expand Up @@ -211,7 +179,7 @@ Zero uses PostgreSQL for storing data. Here's how to set it up:
Run this command to start a local PostgreSQL instance:

```bash
bun docker:db:up
pnpm docker:up
```

This creates a database with:
Expand All @@ -223,7 +191,7 @@ Zero uses PostgreSQL for storing data. Here's how to set it up:

2. **Set Up Database Connection**

Make sure your database connection string is in `.env` file. And you have ran `bun run cf-install` to sync the latest env.
Make sure your database connection string is in `.env` file. And you have ran `pnpm run cf-install` to sync the latest env.

For local development use:

Expand All @@ -236,26 +204,26 @@ Zero uses PostgreSQL for storing data. Here's how to set it up:
- **Set up database tables**:

```bash
bun db:push
pnpm db:push
```

- **Create migration files** (after schema changes):

```bash
bun db:generate
pnpm db:generate
```

- **Apply migrations**:

```bash
bun db:migrate
pnpm db:migrate
```

- **View database content**:
```bash
bun db:studio
pnpm db:studio
```
> If you run `bun dev` in your terminal, the studio command should be automatically running with the app.
> If you run `pnpm dev` in your terminal, the studio command should be automatically running with the app.

## Contribute

Expand Down
4 changes: 1 addition & 3 deletions apps/mail/app/(auth)/login/error-message.tsx
Original file line number Diff line number Diff line change
@@ -1,7 +1,5 @@
'use client';

import { TriangleAlert } from 'lucide-react';
import { useTranslations } from 'next-intl';
import { useTranslations } from 'use-intl';
import { useQueryState } from 'nuqs';
import { useEffect } from 'react';
import { toast } from 'sonner';
Expand Down
18 changes: 7 additions & 11 deletions apps/mail/app/(auth)/login/login-client.tsx
Original file line number Diff line number Diff line change
@@ -1,15 +1,11 @@
'use client';

import { useEffect, type ReactNode, useState, Suspense } from 'react';
import type { EnvVarInfo } from '@zero/server/auth-providers';
import ErrorMessage from '@/app/(auth)/login/error-message';
import { signIn, useSession } from '@/lib/auth-client';
import { Google, Microsoft } from '@/components/icons/icons';
import { Button } from '@/components/ui/button';
import { TriangleAlert } from 'lucide-react';
import { useRouter } from 'next/navigation';
import { env } from '@/lib/env';
import Image from 'next/image';
import { useNavigate } from 'react-router';
import { toast } from 'sonner';

interface EnvVarStatus {
Expand Down Expand Up @@ -48,14 +44,14 @@ const getProviderIcon = (providerId: string, className?: string): ReactNode => {
case 'zero':
return (
<>
<Image
<img
src="/white-icon.svg"
alt="Zero"
width={15}
height={15}
className="mr-2 hidden dark:block"
/>
<Image
<img
src="/black-icon.svg"
alt="Zero"
width={15}
Expand All @@ -70,15 +66,15 @@ const getProviderIcon = (providerId: string, className?: string): ReactNode => {
};

function LoginClientContent({ providers, isProd }: LoginClientProps) {
const router = useRouter();
const navigate = useNavigate();
const [expandedProviders, setExpandedProviders] = useState<Record<string, boolean>>({});

useEffect(() => {
const missing = providers.find((p) => p.required && !p.enabled);
if (missing?.id) {
setExpandedProviders({ [missing.id]: true });
}
}, [providers, router]);
}, [providers]);

const missingRequiredProviders = providers
.filter((p) => p.required && !p.enabled)
Expand Down Expand Up @@ -110,12 +106,12 @@ function LoginClientContent({ providers, isProd }: LoginClientProps) {

const handleProviderClick = (provider: Provider) => {
if (provider.isCustom && provider.customRedirectPath) {
router.push(provider.customRedirectPath);
navigate(provider.customRedirectPath);
} else {
toast.promise(
signIn.social({
provider: provider.id as any,
callbackURL: `${env.NEXT_PUBLIC_APP_URL}/mail`,
callbackURL: `${window.location.origin}/mail`,
}),
{
error: 'Login redirect failed',
Expand Down
27 changes: 14 additions & 13 deletions apps/mail/app/(auth)/login/page.tsx
Original file line number Diff line number Diff line change
@@ -1,18 +1,10 @@
import { authProviders, customProviders, isProviderEnabled } from '@zero/server/auth-providers';
import { authProxy } from '@/lib/auth-proxy';
import { LoginClient } from './login-client';
import { redirect } from 'next/navigation';
import { headers } from 'next/headers';
import { env } from '@/lib/env';

export default async function LoginPage() {
const headersList = new Headers(Object.fromEntries(await (await headers()).entries()));
const session = await authProxy.api.getSession({ headers: headersList });
if (session?.connectionId) {
redirect('/mail/inbox');
}
const envNodeEnv = env.NODE_ENV;
const isProd = envNodeEnv === 'production';
import { useLoaderData } from 'react-router';
import { env } from 'cloudflare:workers';

export function loader() {
const isProd = !import.meta.env.DEV;

const authProviderStatus = authProviders(env as unknown as Record<string, string>).map(
(provider) => {
Expand Down Expand Up @@ -51,6 +43,15 @@ export default async function LoginPage() {

const allProviders = [...customProviderStatus, ...authProviderStatus];

return {
allProviders,
isProd,
};
}

export default function LoginPage() {
const { allProviders, isProd } = useLoaderData<typeof loader>();

return (
<div className="flex min-h-screen w-full flex-col bg-white dark:bg-black">
<LoginClient providers={allProviders} isProd={isProd} />
Expand Down
Loading