Skip to content

Commit

Permalink
Merge branch 'chore-admin-file-structure' of github.com:makeplane/pla…
Browse files Browse the repository at this point in the history
…ne into develop
  • Loading branch information
sriramveeraghanta committed May 8, 2024
2 parents c04fd2d + cbdd2ba commit 9024fd8
Show file tree
Hide file tree
Showing 44 changed files with 271 additions and 1,045 deletions.
6 changes: 3 additions & 3 deletions admin/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -23,11 +23,11 @@
"lucide-react": "^0.356.0",
"mobx": "^6.12.0",
"mobx-react-lite": "^4.0.5",
"next": "^14.1.0",
"next": "^14.2.3",
"next-themes": "^0.2.1",
"postcss": "8.4.23",
"react": "^18.2.0",
"react-dom": "^18.2.0",
"react": "^18.3.1",
"react-dom": "^18.3.1",
"react-hook-form": "^7.51.0",
"swr": "^2.2.4",
"tailwindcss": "3.3.2",
Expand Down
2 changes: 1 addition & 1 deletion admin/services/api.service.ts
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ export abstract class APIService {
(response) => response,
(error) => {
if (error.response && error.response.status === 401) window.location.href = "/login";
return Promise.reject(error.response?.data ?? error);
return Promise.reject(error);
}
);
}
Expand Down
57 changes: 34 additions & 23 deletions apiserver/plane/authentication/adapter/error.py
Original file line number Diff line number Diff line change
@@ -1,37 +1,48 @@
AUTHENTICATION_ERROR_CODES = {
# Global
"INSTANCE_NOT_CONFIGURED": 5000,
"INVALID_EMAIL": 5012,
"EMAIL_REQUIRED": 5013,
"SIGNUP_DISABLED": 5001,
# Password strength
"INVALID_PASSWORD": 5002,
"SMTP_NOT_CONFIGURED": 5007,
# Sign Up
"USER_ALREADY_EXIST": 5003,
"AUTHENTICATION_FAILED_SIGN_UP": 5006,
"REQUIRED_EMAIL_PASSWORD_SIGN_UP": 5015,
"INVALID_EMAIL_SIGN_UP": 5017,
"INVALID_EMAIL_MAGIC_SIGN_UP": 5019,
"MAGIC_SIGN_UP_EMAIL_CODE_REQUIRED": 5023,
# Sign In
"USER_DOES_NOT_EXIST": 5004,
"AUTHENTICATION_FAILED_SIGN_IN": 5005,
"AUTHENTICATION_FAILED_SIGN_UP": 5006,
"SMTP_NOT_CONFIGURED": 5007,
"REQUIRED_EMAIL_PASSWORD_SIGN_IN": 5014,
"INVALID_EMAIL_SIGN_IN": 5016,
"INVALID_EMAIL_MAGIC_SIGN_IN": 5018,
"MAGIC_SIGN_IN_EMAIL_CODE_REQUIRED": 5022,
# Both Sign in and Sign up
"INVALID_MAGIC_CODE": 5008,
"EXPIRED_MAGIC_CODE": 5009,
# Oauth
"GOOGLE_NOT_CONFIGURED": 5010,
"GITHUB_NOT_CONFIGURED": 5011,
"INVALID_EMAIL": 5012,
"EMAIL_REQUIRED": 5013,
"REQUIRED_EMAIL_PASSWORD_SIGN_IN": 5014,
"INVALID_EMAIL_SIGN_IN": 5015,
"INVALID_EMAIL_SIGN_UP": 5016,
"INVALID_EMAIL_MAGIC_SIGN_IN": 5017,
"INVALID_EMAIL_MAGIC_SIGN_UP": 5018,
"GITHUB_OAUTH_PROVIDER_ERROR": 5019,
"GOOGLE_OAUTH_PROVIDER_ERROR": 5020,
"MAGIC_SIGN_IN_EMAIL_CODE_REQUIRED": 5021,
"MAGIC_SIGN_UP_EMAIL_CODE_REQUIRED": 5022,
"INVALID_PASSWORD_TOKEN": 5023,
"EXPIRED_PASSWORD_TOKEN": 5024,
"INCORRECT_OLD_PASSWORD": 5025,
"INVALID_NEW_PASSWORD": 5026,
"PASSWORD_ALREADY_SET": 5027,
"ADMIN_ALREADY_EXIST": 5028,
"REQUIRED_ADMIN_EMAIL_PASSWORD_FIRST_NAME": 5029,
"INVALID_ADMIN_EMAIL": 5030,
"INVALID_ADMIN_PASSWORD": 5031,
"REQUIRED_ADMIN_EMAIL_PASSWORD": 5032,
"GOOGLE_OAUTH_PROVIDER_ERROR": 5021,
"GITHUB_OAUTH_PROVIDER_ERROR": 5020,
# Reset Password
"INVALID_PASSWORD_TOKEN": 5024,
"EXPIRED_PASSWORD_TOKEN": 5025,
# Change password
"INCORRECT_OLD_PASSWORD": 5026,
"INVALID_NEW_PASSWORD": 5027,
# set passowrd
"PASSWORD_ALREADY_SET": 5028,
# Admin
"ADMIN_ALREADY_EXIST": 5029,
"REQUIRED_ADMIN_EMAIL_PASSWORD_FIRST_NAME": 5030,
"INVALID_ADMIN_EMAIL": 5031,
"INVALID_ADMIN_PASSWORD": 5032,
"REQUIRED_ADMIN_EMAIL_PASSWORD": 5033,
"ADMIN_AUTHENTICATION_FAILED": 5034,
"ADMIN_USER_ALREADY_EXIST": 5035,
"ADMIN_USER_DOES_NOT_EXIST": 5036,
Expand Down
18 changes: 18 additions & 0 deletions apiserver/plane/authentication/adapter/exception.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
from rest_framework.views import exception_handler
from rest_framework.exceptions import NotAuthenticated


def auth_exception_handler(exc, context):
# Call the default exception handler first, to get the standard error response.
response = exception_handler(exc, context)
# Check if an AuthenticationFailed exception is raised.
if isinstance(exc, NotAuthenticated):
# Return 403 if the users me api fails
request = context["request"]
if request.path == "/api/users/me/":
response.status_code = 403
# else return 401
else:
response.status_code = 401

return response
4 changes: 4 additions & 0 deletions apiserver/plane/authentication/utils/host.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,3 +8,7 @@ def base_host(request):
or f"{urlsplit(request.META.get('HTTP_REFERER')).scheme}://{urlsplit(request.META.get('HTTP_REFERER')).netloc}"
or f"{request.scheme}://{request.get_host()}"
)


def user_ip(request):
return str(request.META.get("REMOTE_ADDR"))
5 changes: 5 additions & 0 deletions apiserver/plane/authentication/utils/login.py
Original file line number Diff line number Diff line change
@@ -1,11 +1,16 @@
# Django imports
from django.contrib.auth import login

# Module imports
from plane.authentication.utils.host import base_host


def user_login(request, user):
login(request=request, user=user)
device_info = {
"user_agent": request.META.get("HTTP_USER_AGENT", ""),
"ip_address": request.META.get("REMOTE_ADDR", ""),
"domain": base_host(request=request),
}
request.session["device_info"] = device_info
request.session.save()
Expand Down
27 changes: 20 additions & 7 deletions apiserver/plane/authentication/views/app/signout.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,17 +5,30 @@
from django.views import View
from django.contrib.auth import logout
from django.http import HttpResponseRedirect
from django.utils import timezone

# Module imports
from plane.authentication.utils.host import base_host
from plane.authentication.utils.host import user_ip, base_host
from plane.db.models import User


class SignOutAuthEndpoint(View):

def post(self, request):
logout(request)
url = urljoin(
base_host(request=request),
"accounts/sign-in?" + urlencode({"success": "true"}),
)
return HttpResponseRedirect(url)
# Get user
try:
user = User.objects.get(pk=request.user.id)
user.last_logout_ip = user_ip(request=request)
user.last_logout_time = timezone.now()
user.save()
# Log the user out
logout(request)
url = urljoin(
base_host(request=request),
"accounts/sign-in?" + urlencode({"success": "true"}),
)
return HttpResponseRedirect(url)
except Exception:
return HttpResponseRedirect(
base_host(request=request), "accounts/sign-in"
)
27 changes: 20 additions & 7 deletions apiserver/plane/authentication/views/space/signout.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,17 +5,30 @@
from django.views import View
from django.contrib.auth import logout
from django.http import HttpResponseRedirect
from django.utils import timezone

# Module imports
from plane.authentication.utils.host import base_host
from plane.authentication.utils.host import base_host, user_ip
from plane.db.models import User


class SignOutAuthSpaceEndpoint(View):

def post(self, request):
logout(request)
url = urljoin(
base_host(request=request),
"spaces/accounts/sign-in?" + urlencode({"success": "true"}),
)
return HttpResponseRedirect(url)
# Get user
try:
user = User.objects.get(pk=request.user.id)
user.last_logout_ip = user_ip(request=request)
user.last_logout_time = timezone.now()
user.save()
# Log the user out
logout(request)
url = urljoin(
base_host(request=request),
"accounts/sign-in?" + urlencode({"success": "true"}),
)
return HttpResponseRedirect(url)
except Exception:
return HttpResponseRedirect(
base_host(request=request), "accounts/sign-in"
)
10 changes: 10 additions & 0 deletions apiserver/plane/db/migrations/0065_auto_20240415_0937.py
Original file line number Diff line number Diff line change
Expand Up @@ -257,4 +257,14 @@ class Migration(migrations.Migration):
model_name="user",
name="use_case",
),
migrations.AddField(
model_name="globalview",
name="logo_props",
field=models.JSONField(default=dict),
),
migrations.AddField(
model_name="page",
name="logo_props",
field=models.JSONField(default=dict),
),
]
1 change: 1 addition & 0 deletions apiserver/plane/db/models/page.py
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,7 @@ class Page(ProjectBaseModel):
archived_at = models.DateField(null=True)
is_locked = models.BooleanField(default=False)
view_props = models.JSONField(default=get_view_props)
logo_props = models.JSONField(default=dict)

class Meta:
verbose_name = "Page"
Expand Down
2 changes: 2 additions & 0 deletions apiserver/plane/db/models/view.py
Original file line number Diff line number Diff line change
Expand Up @@ -64,6 +64,7 @@ class GlobalView(BaseModel):
)
query_data = models.JSONField(default=dict)
sort_order = models.FloatField(default=65535)
logo_props = models.JSONField(default=dict)

class Meta:
verbose_name = "Global View"
Expand All @@ -86,6 +87,7 @@ def __str__(self):
return f"{self.name} <{self.workspace.name}>"


# DEPRECATED TODO: - Remove in next release
class IssueView(WorkspaceBaseModel):
name = models.CharField(max_length=255, verbose_name="View Name")
description = models.TextField(verbose_name="View Description", blank=True)
Expand Down
25 changes: 18 additions & 7 deletions apiserver/plane/license/api/views/admin.py
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@
from plane.db.models import User, Profile
from plane.utils.cache import cache_response, invalidate_cache
from plane.authentication.utils.login import user_login
from plane.authentication.utils.host import base_host
from plane.authentication.utils.host import base_host, user_ip
from plane.authentication.adapter.error import (
AUTHENTICATION_ERROR_CODES,
AuthenticationException,
Expand Down Expand Up @@ -402,9 +402,20 @@ class InstanceAdminSignOutEndpoint(View):
]

def post(self, request):
logout(request)
url = urljoin(
base_host(request=request),
"god-mode/login?" + urlencode({"success": "true"}),
)
return HttpResponseRedirect(url)
# Get user
try:
user = User.objects.get(pk=request.user.id)
user.last_logout_ip = user_ip(request=request)
user.last_logout_time = timezone.now()
user.save()
# Log the user out
logout(request)
url = urljoin(
base_host(request=request),
"accounts/sign-in?" + urlencode({"success": "true"}),
)
return HttpResponseRedirect(url)
except Exception:
return HttpResponseRedirect(
base_host(request=request), "accounts/sign-in"
)
1 change: 1 addition & 0 deletions apiserver/plane/settings/common.py
Original file line number Diff line number Diff line change
Expand Up @@ -78,6 +78,7 @@
"DEFAULT_FILTER_BACKENDS": (
"django_filters.rest_framework.DjangoFilterBackend",
),
"EXCEPTION_HANDLER": "plane.authentication.adapter.exception.auth_exception_handler",
}

# Django Auth Backend
Expand Down
4 changes: 4 additions & 0 deletions nginx/nginx.conf.template
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,10 @@ http {
proxy_pass http://admin:3000/god-mode/;
}

location /auth/ {
proxy_pass http://api:8000/auth/;
}

location /${BUCKET_NAME}/ {
proxy_pass http://plane-minio:9000/${BUCKET_NAME}/;
}
Expand Down
10 changes: 5 additions & 5 deletions space/helpers/authentication.helper.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,11 +2,11 @@ import { ReactNode } from "react";
import Link from "next/link";

export enum EPageTypes {
"INIT" = "INIT",
"PUBLIC" = "PUBLIC",
"NON_AUTHENTICATED" = "NON_AUTHENTICATED",
"ONBOARDING" = "ONBOARDING",
"AUTHENTICATED" = "AUTHENTICATED",
INIT = "INIT",
PUBLIC = "PUBLIC",
NON_AUTHENTICATED = "NON_AUTHENTICATED",
ONBOARDING = "ONBOARDING",
AUTHENTICATED = "AUTHENTICATED",
}

export enum EAuthModes {
Expand Down
9 changes: 6 additions & 3 deletions space/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -28,17 +28,19 @@
"dompurify": "^3.0.11",
"dotenv": "^16.3.1",
"js-cookie": "^3.0.1",
"lodash": "^4.17.21",
"lowlight": "^2.9.0",
"lucide-react": "^0.378.0",
"mobx": "^6.10.0",
"mobx-react-lite": "^4.0.3",
"next": "^14.0.3",
"next": "^14.2.3",
"next-themes": "^0.2.1",
"nprogress": "^0.2.0",
"react": "^18.2.0",
"react-dom": "^18.2.0",
"react": "^18.3.1",
"react-dom": "^18.3.1",
"react-dropzone": "^14.2.3",
"react-hook-form": "^7.38.0",
"react-popper": "^2.3.0",
"swr": "^2.2.2",
"tailwind-merge": "^2.0.0",
"typescript": "4.9.5",
Expand All @@ -48,6 +50,7 @@
"devDependencies": {
"@types/dompurify": "^3.0.5",
"@types/js-cookie": "^3.0.3",
"@types/lodash": "^4.17.1",
"@types/node": "18.14.1",
"@types/nprogress": "^0.2.0",
"@types/react": "^18.2.42",
Expand Down
8 changes: 4 additions & 4 deletions space/pages/_app.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -32,13 +32,13 @@ function MyApp({ Component, pageProps }: AppProps) {
<link rel="shortcut icon" href={`${prefix}favicon/favicon.ico`} />
</Head>
<StoreProvider>
<ToastContextProvider>
<ThemeProvider themes={["light", "dark"]} defaultTheme="system" enableSystem>
<ThemeProvider themes={["light", "dark"]} defaultTheme="system" enableSystem>
<ToastContextProvider>
<InstanceWrapper>
<Component {...pageProps} />
</InstanceWrapper>
</ThemeProvider>
</ToastContextProvider>
</ToastContextProvider>
</ThemeProvider>
</StoreProvider>
</>
);
Expand Down
2 changes: 1 addition & 1 deletion space/services/api.service.ts
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ abstract class APIService {
(response) => response,
(error) => {
if (error.response && error.response.status === 401) window.location.href = "/";
return Promise.reject(error.response?.data ?? error);
return Promise.reject(error);
}
);
}
Expand Down
7 changes: 5 additions & 2 deletions web/components/account/auth-forms/auth-root.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -84,8 +84,11 @@ export const AuthRoot: FC<TAuthRoot> = observer((props) => {
authMode === EAuthModes.SIGN_IN ? authService.signInEmailCheck(data) : authService.signUpEmailCheck(data);

await emailCheckRequest
.then(() => {
setAuthStep(EAuthSteps.PASSWORD);
.then((response) => {
if (authMode === EAuthModes.SIGN_IN) {
if (response.is_password_autoset) setAuthStep(EAuthSteps.UNIQUE_CODE);
else setAuthStep(EAuthSteps.PASSWORD);
} else setAuthStep(EAuthSteps.PASSWORD);
})
.catch((error) => {
const errorhandler = authErrorHandler(error?.error_code.toString(), data?.email || undefined);
Expand Down
Loading

0 comments on commit 9024fd8

Please sign in to comment.