Skip to content

Commit

Permalink
Merge branch 'main' into dependabot/pip/backend/django-4.2.3
Browse files Browse the repository at this point in the history
  • Loading branch information
rohan-chaturvedi authored Jul 15, 2023
2 parents dfbb811 + 2151cfd commit 351c39b
Show file tree
Hide file tree
Showing 15 changed files with 235 additions and 36 deletions.
2 changes: 1 addition & 1 deletion .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -131,7 +131,7 @@ dmypy.json
# See https://help.github.com/articles/ignoring-files/ for more about ignoring files.

# dependencies
/node_modules
/frontend/node_modules
/.pnp
.pnp.js

Expand Down
17 changes: 13 additions & 4 deletions CONTRIBUTING.md
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ If you're ever in doubt about whether or not a proposed feature aligns with Phas

## Writing and submitting code

Anyone can contribute code to Phase. To get started, check out the local development guide, make your changes, and submit a pull request to the main repository.
Anyone can contribute code to Phase. To get started, check out the local development guide, make your changes, and submit a pull request to the main repository. When committing code, please try and use [conventional commits](https://www.conventionalcommits.org/en/v1.0.0/).

## Licensing

Expand All @@ -36,6 +36,15 @@ Any third party components incorporated into our code are licensed under the ori

## Setup local development environment

1. Create a `.env.dev` file with `cp .env.dev.example .env.dev` and add atleast one OAuth provider
2. `docker-compose -f dev-docker-compose.yml up`
3. The Console is now running at `https://localhost` with HMR
### Dev server with hot reload

1. Create a `.env.dev` file with `cp .env.dev.example .env.dev` and add atleast one OAuth provider.
2. `docker-compose -f dev-docker-compose.yml up`.
3. The Console is now running at `https://localhost` with HMR.

### Staging env to test production builds

1. Set up a `.env` file with `cp .env.example` and add atleast one OAuth provider. View the [docs](https://docs.phase.dev/self-hosting/configuration/envars) for more info.
2. Build the image locally with `docker-compose -f staging-docker-compose.yml build`
3. Bring docker compose up with `docker-compose -f staging-docker-compose.yml up`
4. The Console is now running at `https://localhost`.
8 changes: 4 additions & 4 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@

[Phase Console](https://phase.dev) is an open source, end-to-end encrypted key management solution for developers to seamlessly encrypt production data in their apps.

We're on a mission to make strong encryption accessible to all developers not just security teams. That means redesigning the entire developer experience from the ground up.
We're on a mission to make strong encryption accessible to all developers, not just security teams. That means redesigning the entire developer experience from the ground up.

## Features

Expand Down Expand Up @@ -95,23 +95,23 @@ const ciphertext = await phase.encrypt('hello world')

// Decrypt
const plaintext = await phase.decrypt(ciphertext)
console.log(ciphertext)
console.log(plaintext)
$ hello world
```

---

## Community vs Enterprise edition

Phase operates on a [open-core](https://en.wikipedia.org/wiki/Open-core_model) model, similar to that of [GitLab](https://gitlab.com), [Infisical](https://infisical.com), [PostHog](https://posthog.com) etc.
Phase operates on an [open-core](https://en.wikipedia.org/wiki/Open-core_model) model, similar to that of [GitLab](https://gitlab.com), [Infisical](https://infisical.com), [PostHog](https://posthog.com) etc.

This repo available under the [MIT expat license](/LICENSE), with the exception of the `ee` directory which will contain premium Pro or Enterprise features requiring a Phase license in the future.

---

## Security

For more information of how Phase encryption works, please see the [Security Docs](https://docs.phase.dev/security)
For more information on how Phase encryption works, please see the [Security Docs](https://docs.phase.dev/security)

Please do not file GitHub issues or post on our public forum for security vulnerabilities, as they are public!

Expand Down
4 changes: 2 additions & 2 deletions backend/requirements.txt
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ certifi==2022.12.7
cffi==1.15.1
charset-normalizer==3.0.1
constantly==15.1.0
cryptography==41.0.0
cryptography==41.0.2
defusedxml==0.7.1
dj-rest-auth==3.0.0
Django==4.2.3
Expand Down Expand Up @@ -39,7 +39,7 @@ pyOpenSSL==23.2.0
python-dateutil==2.8.2
python3-openid==3.2.0
pytz==2022.7.1
requests==2.28.2
requests==2.31.0
requests-oauthlib==1.3.1
service-identity==21.1.0
six==1.16.0
Expand Down
23 changes: 18 additions & 5 deletions frontend/Dockerfile
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,15 @@
FROM node:alpine AS base
# set working directory
WORKDIR /app

# Add a new user "app" and change ownership of the /app directory
RUN addgroup app && adduser -S -G app app && chown -R app:app /app

# Switch to the new user "app"
USER app

# copy project file
COPY package.json yarn.lock ./
COPY --chown=app:app package.json yarn.lock ./

# ---- Dependencies ----
FROM base AS dependencies
Expand All @@ -16,11 +23,12 @@ RUN yarn install --frozen-lockfile

# ---- Build ----
FROM dependencies AS build
COPY . .
COPY --chown=app:app . .

# Set environment variables
ARG NEXT_PUBLIC_BACKEND_API_BASE=BAKED_NEXT_PUBLIC_BACKEND_API_BASE
ARG NEXT_PUBLIC_NEXTAUTH_PROVIDERS=BAKED_NEXT_PUBLIC_NEXTAUTH_PROVIDERS
ARG NEXT_PUBLIC_APP_HOST=BAKED_NEXT_PUBLIC_APP_HOST
RUN yarn build

# ---- Release ----
Expand All @@ -31,10 +39,15 @@ COPY --from=dependencies /tmp/node_modules ./node_modules
COPY --from=build /app/.next ./.next
COPY --from=build /app/public ./public
# copy scripts directory
COPY scripts ./scripts
COPY --chown=app:app scripts ./scripts
# copy next config
COPY next.config.js ./
# expose port and define CMD
COPY --chown=app:app next.config.js ./

# Switch back to root to change permissions and then back to app user
USER root
RUN chmod 555 ./scripts/*
USER app

# expose port and define CMD
EXPOSE 3000
CMD ["/app/scripts/start.sh"]
4 changes: 2 additions & 2 deletions frontend/apollo/client.ts
Original file line number Diff line number Diff line change
Expand Up @@ -33,10 +33,10 @@ const errorLink = onError(({ graphQLErrors, networkError, operation, forward })
}
}

// To retry on network errors, we recommend the RetryLink
// instead of the onError link. This just logs the error.
// Log network error
if (networkError) {
console.log(`[Network error]: ${networkError}`)
// Client-side logout when recieving a 403 from the backend
if (networkError.message.includes('403')) handleSignout()
}
})
Expand Down
6 changes: 3 additions & 3 deletions frontend/app/[team]/newdevice/page.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -110,6 +110,9 @@ export default function NewDevice({ params }: { params: { team: string } }) {
return (
<>
<div className="flex flex-col justify-between w-full h-screen">
<div className="w-full flex justify-end p-4">
<UserMenu />
</div>
<div className="flex flex-col mx-auto my-auto w-full max-w-3xl gap-y-8">
<div className="mx-auto max-w-xl">
<h1 className="text-4xl text-black dark:text-white text-center font-bold">
Expand Down Expand Up @@ -153,9 +156,6 @@ export default function NewDevice({ params }: { params: { team: string } }) {
</div>
</form>
</div>
<div className="w-full p-4">
<UserMenu />
</div>
</div>
</>
)
Expand Down
13 changes: 7 additions & 6 deletions frontend/components/UserMenu.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ import { ChevronDownIcon } from '@heroicons/react/20/solid'
import { useSession, signIn, signOut } from 'next-auth/react'
import { MdLogout } from 'react-icons/md'
import { handleSignout } from '@/apollo/client'
import { Button } from './common/Button'

export default function UserMenu() {
const { data: session } = useSession()
Expand All @@ -15,15 +16,15 @@ export default function UserMenu() {
return (
<div className="">
<Menu as="div" className="relative inline-block text-left">
<div>
<Menu.Button className="inline-flex w-full justify-center items-center gap-2 rounded-full text-xs font-medium text-black dark:text-white hover:text-emerald-500 dark:hover:text-emerald-500 hover:bg-opacity-30 focus:outline-none focus-visible:ring-2 focus-visible:ring-white focus-visible:ring-opacity-75">
<div
className="h-8 w-8 rounded-full bg-center bg-cover bg-no-repeat ring-white"
<Menu.Button as="div">
<Button variant="secondary">
<div
className="h-5 w-5 mr-1 rounded-full bg-center bg-cover bg-no-repeat ring-white"
style={{ backgroundImage: `url(${session?.user?.image})` }}
></div>
<div className="flex flex-col">{firstName}</div>
</Menu.Button>
</div>
</Button>
</Menu.Button>
<Transition
as={Fragment}
enter="transition ease-out duration-100"
Expand Down
2 changes: 1 addition & 1 deletion frontend/components/apps/NewAppDialog.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,7 @@ export default function NewAppDialog(props: {
const { data: session } = useSession()
const [createApp, { data, loading, error }] = useMutation(CreateApp)

const IS_CLOUD_HOSTED = process.env.APP_HOST === 'cloud'
const IS_CLOUD_HOSTED = process.env.APP_HOST || process.env.NEXT_PUBLIC_APP_HOST

const DEFAULT_BUTTON = {
label: 'Create an app',
Expand Down
82 changes: 82 additions & 0 deletions frontend/components/common/StatusIndicator.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,82 @@
'use client'

import Link from 'next/link'
import { Button } from './Button'
import { useEffect, useState } from 'react'
import clsx from 'clsx'

type Status = {
indicator: 'none' | 'minor' | 'major' | 'critical' | 'error'
description: string
}

const STATUS_PAGE_BASE_URL = 'https://phase.statuspage.io'

export const StatusIndicator = () => {

const [status, setStatus] = useState<Status | null>(null)
const [isLoading, setLoading] = useState<boolean>(false)

useEffect(() => {
const getStatus = async () => {

setLoading(true)
try {
await fetch(`${STATUS_PAGE_BASE_URL}/api/v2/status.json`).then(res => {
setLoading(false)
if (!res.ok) throw ('Fetch error')
else {
res.json().then(json => {
setStatus(json.status)
})
}
})
} catch (e) {
console.log(`Error getting system status: ${e}`)
setLoading(false)
setStatus({
indicator: 'error',
description: 'Error fetching status'
})
}
}

getStatus()
}, [])

const statusColor = () => {
let color = 'bg-neutral-500'
switch (status?.indicator) {
case 'none':
color = 'bg-emerald-500'
break
case 'minor':
color = 'bg-yellow-500'
break
case 'major':
color = 'bg-orange-500'
break
case 'critical':
color = 'bg-red-500'
break
default:
color = 'bg-neutral-500'
}
return color
}

return (
<Link href={STATUS_PAGE_BASE_URL} target="_blank">
<Button variant="secondary">
<span
className={clsx(
'h-2 w-2 mr-1 rounded-full',
statusColor(),
isLoading && 'animate-pulse'
)}
></span>
{status?.description || 'Loading'}
</Button>
</Link>
)
}
10 changes: 9 additions & 1 deletion frontend/components/layout/Navbar.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -7,11 +7,15 @@ import { usePathname } from 'next/navigation'
import { useEffect } from 'react'
import { AppType } from '@/apollo/graphql'
import Link from 'next/link'
import { Button } from '../common/Button'
import { StatusIndicator } from '../common/StatusIndicator'

export const NavBar = (props: { team: string }) => {
const { data: orgsData } = useQuery(GetOrganisations)
const [getApps, { data: appsData }] = useLazyQuery(GetApps)

const IS_CLOUD_HOSTED = process.env.APP_HOST || process.env.NEXT_PUBLIC_APP_HOST

useEffect(() => {
if (orgsData?.organisations) {
const fetchData = async () => {
Expand Down Expand Up @@ -48,7 +52,11 @@ export const NavBar = (props: { team: string }) => {
{activeApp && <span>/</span>}
{activeApp && <span className="text-black dark:text-white">{activeApp.name}</span>}
</div>
<UserMenu />
<div className="flex gap-4 items-center justify-end">
{IS_CLOUD_HOSTED && <StatusIndicator />}
<Link href="https://docs.phase.dev" target="_blank"><Button variant="secondary">Docs</Button></Link>
<UserMenu />
</div>
</header>
)
}
4 changes: 2 additions & 2 deletions frontend/next.config.js
Original file line number Diff line number Diff line change
Expand Up @@ -5,10 +5,10 @@ const ContentSecurityPolicy = `
style-src 'self' 'unsafe-inline';
object-src 'none';
base-uri 'self';
connect-src 'self' data: ${process.env.NEXT_PUBLIC_BACKEND_API_BASE};
connect-src 'self' data: https://*.phase.dev https://phase.statuspage.io/api/v2/status.json;
font-src 'self';
frame-src 'self';
img-src 'self' https://lh3.googleusercontent.com https://avatars.githubusercontent.com https://secure.gravatar.com;
img-src 'self' https://lh3.googleusercontent.com https://avatars.githubusercontent.com https://secure.gravatar.com https://gitlab.com;
manifest-src 'self';
media-src 'self';
worker-src 'none';
Expand Down
14 changes: 13 additions & 1 deletion frontend/scripts/replace-variable.sh
Original file line number Diff line number Diff line change
@@ -1,7 +1,19 @@
#!/bin/sh
#!/bin/bash

# Ensure NEXT_PUBLIC_BACKEND_API_BASE and NEXT_PUBLIC_NEXTAUTH_PROVIDERS are set
if [ -z "$NEXT_PUBLIC_BACKEND_API_BASE" ]; then
echo "NEXT_PUBLIC_BACKEND_API_BASE is not set. Please set it and rerun the script."
exit 1
fi

if [ -z "$NEXT_PUBLIC_NEXTAUTH_PROVIDERS" ]; then
echo "NEXT_PUBLIC_NEXTAUTH_PROVIDERS is not set. Please set it and rerun the script."
exit 1
fi

find /app/public /app/.next -type f -name "*.js" |
while read file; do
sed -i "s|BAKED_NEXT_PUBLIC_BACKEND_API_BASE|$NEXT_PUBLIC_BACKEND_API_BASE|g" "$file"
sed -i "s|BAKED_NEXT_PUBLIC_NEXTAUTH_PROVIDERS|$NEXT_PUBLIC_NEXTAUTH_PROVIDERS|g" "$file"
sed -i "s|BAKED_NEXT_PUBLIC_APP_HOST|$APP_HOST|g" "$file"
done
6 changes: 2 additions & 4 deletions frontend/scripts/start.sh
Original file line number Diff line number Diff line change
@@ -1,7 +1,5 @@
#!/bin/sh

# Set up runtime env vars
scripts/replace-variable.sh

# Start your Next.js app
# Set up runtime env vars and start next server
sh scripts/replace-variable.sh &&
yarn start
Loading

0 comments on commit 351c39b

Please sign in to comment.