Skip to content

Commit

Permalink
Merge branch 'release/1.0.1'
Browse files Browse the repository at this point in the history
  • Loading branch information
chiachunho committed Jun 9, 2021
2 parents f81df0f + e5bb463 commit 1247590
Show file tree
Hide file tree
Showing 37 changed files with 640 additions and 293 deletions.
43 changes: 43 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
# Changelog
All notable changes to this project will be documented in this file.

The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).

## [1.0.1] - 2021-06-10

### Added

- ReadMe.md
- License based on MIT License
- Add `localhost` to Django Production `ALLOW_HOSTS` list
- Add username field to jwt token and get username by parse token
- `GameConsumer` check event permission
- React.js Frontend Project
- Docker-compose dev/prod/ci settings
- additional text to guide user to signup/login page

### Changed

- Fix django account can't delete because of `outstanding token` delete permission
- Fix Game page title room name `undefined`
- Fix bystander can view one of player handcards
- Adjust docker-compose dev/prod/ci settings
- Fix frontend `access_token` not exist error handling
- Fix frontend `GameSwitch` & ` AccountSwitch` not handle 404
- Adjust footer to stick on bottom
- Adjust GamePlaying Page layout
- Change django time-zone and language
- Unify card name and so on

### Removed

- Frontend Code console log for debug
- Backend Code unused comment

## [1.0.0] - 2021-05-28
### Added
- Finished Saboteur Game Website
- Django Backend Project
- React.js Frontend Project
- Docker-compose dev/prod/ci settings
26 changes: 26 additions & 0 deletions LICENSE
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
License

Copyright (c) 2021 NTNU OOAD Project

This project is a digital version of the well-known board game Saboteur, so
all the copyrights of the game content belong to the game company. Therefore,
we do not recommend that you use it for a commercial profit. In this project,
we used it for academic reference only.

Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and to permit
persons to whom the Software is furnished to do so, subject to the following
conditions:

The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
4 changes: 3 additions & 1 deletion docker-compose.ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ services:
restart: always
volumes:
- ./nginx/log:/var/log/nginx
- ./mysite:/docker_django
networks:
- proxy
depends_on:
Expand All @@ -21,10 +22,11 @@ services:
- LETSENCRYPT_EMAIL=${LETSENCRYPT_EMAIL}

app:
container_name: ooad-django
build:
context: ./mysite
dockerfile: Dockerfile.ci
volumes:
- ./mysite:/mysite
networks:
- proxy
- default
Expand Down
15 changes: 15 additions & 0 deletions docker-compose.override.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
version: '3'
services:

db:
ports:
- "5432:5432"

redis:
ports:
- "6379:6379"

app:
ports:
- "8000:8000"

6 changes: 0 additions & 6 deletions docker-compose.prod.yml
Original file line number Diff line number Diff line change
Expand Up @@ -22,19 +22,13 @@ services:
- LETSENCRYPT_EMAIL=${LETSENCRYPT_EMAIL}

app:
container_name: ooad-django
build:
context: ./mysite
dockerfile: Dockerfile.prod
volumes:
- django-data:/mysite
networks:
- proxy
- default

volumes:
django-data:

networks:
proxy:
external:
Expand Down
31 changes: 8 additions & 23 deletions docker-compose.yml
Original file line number Diff line number Diff line change
@@ -1,29 +1,13 @@
version: '3'
services:

nginx:
container_name: ooad-nginx
build: ./nginx
restart: always
volumes:
- ./nginx/log:/var/log/nginx
- ./mysite:/docker_django
depends_on:
- app
environment:
- VIRTUAL_HOST=${VIRTUAL_HOST}
- VIRTUAL_NETWORK=${VIRTUAL_NETWORK}
- VIRTUAL_PORT=${VIRTUAL_PORT}
- LETSENCRYPT_HOST=${LETSENCRYPT_HOST}
- LETSENCRYPT_EMAIL=${LETSENCRYPT_EMAIL}

redis:
container_name: ooad-redis
image: redis
restart: always
command: ["redis-server", "--appendonly", "yes"]
ports:
- "6379:6379"
expose:
- 6379
volumes:
- redis-data:/data
depends_on:
Expand All @@ -38,10 +22,10 @@ services:
python manage.py migrate &&
daphne -b 0.0.0.0 -p 8000 mysite.asgi:application"
restart: always
ports:
- "8000:8000"
expose:
- 8000
volumes:
- ./mysite:/mysite
- django-data:/mysite
environment:
- SECRET_KEY=${SECRET_KEY}
- POSTGRES_PASSWORD=${POSTGRES_PASSWORD}
Expand All @@ -52,8 +36,8 @@ services:
db:
container_name: ooad-postgres
restart: always
ports:
- "5432:5432"
expose:
- 5432
image: postgres
environment:
- POSTGRES_PASSWORD=${POSTGRES_PASSWORD}
Expand All @@ -63,4 +47,5 @@ services:
volumes:
redis-data:
pgdata:
django-data:

11 changes: 11 additions & 0 deletions mysite/authentication/admin.py
Original file line number Diff line number Diff line change
@@ -1,9 +1,20 @@
from django.contrib import admin
from rest_framework_simplejwt.token_blacklist.admin import OutstandingTokenAdmin
from rest_framework_simplejwt.token_blacklist import models

from .models import CustomUser


class CustomUserAdmin(admin.ModelAdmin):
model = CustomUser


class NewOutstandingTokenAdmin(OutstandingTokenAdmin):

def has_delete_permission(self, *args, **kwargs):
return True


admin.site.unregister(models.OutstandingToken)
admin.site.register(models.OutstandingToken, NewOutstandingTokenAdmin)
admin.site.register(CustomUser, CustomUserAdmin)
1 change: 0 additions & 1 deletion mysite/authentication/models.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,4 +4,3 @@

class CustomUser(AbstractUser):
color = models.CharField(blank=True, max_length=120)
# Create your models here.
4 changes: 2 additions & 2 deletions mysite/authentication/serializers.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,11 +6,11 @@
class MyTokenObtainPairSerializer(TokenObtainPairSerializer):

@classmethod
def get_token(cls, user):
def get_token(cls, user: CustomUser):
token = super(MyTokenObtainPairSerializer, cls).get_token(user)

# Add custom claims
token['color'] = user.color
token['username'] = user.username
return token


Expand Down
1 change: 1 addition & 0 deletions mysite/frontend/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
"dependencies": {
"@fortawesome/fontawesome-free": "^5.15.3",
"@fortawesome/fontawesome-svg-core": "^1.2.35",
"@fortawesome/free-brands-svg-icons": "^5.15.3",
"@fortawesome/free-solid-svg-icons": "^5.15.3",
"@fortawesome/react-fontawesome": "^0.1.14",
"@testing-library/jest-dom": "^5.12.0",
Expand Down
15 changes: 12 additions & 3 deletions mysite/frontend/src/api/Api.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,9 +3,9 @@ import axios from 'axios';
let APIbaseURL;

if (process.env.NODE_ENV === 'production') {
APIbaseURL = window.location.origin + /api/;
APIbaseURL = window.location.origin + '/api/';
} else {
APIbaseURL = process.env.REACT_APP_API_URL;
APIbaseURL = process.env.REACT_APP_API_URL || 'http://localhost:8000/api/';
}

const axiosInstance = axios.create({
Expand Down Expand Up @@ -34,6 +34,8 @@ axiosInstance.interceptors.response.use(
// Prevent infinite loops
if (error.response.status === 401 && originalRequest.url === '/auth/token/refresh/') {
localStorage.removeItem('username');
localStorage.removeItem('access_token');
localStorage.removeItem('refresh_token');
window.location.href = `/account/login/?next=${window.location.pathname}`;
return Promise.reject(error);
}
Expand All @@ -46,7 +48,6 @@ axiosInstance.interceptors.response.use(

// exp date in token is expressed in seconds, while now() returns milliseconds:
const now = Math.ceil(Date.now() / 1000);
console.log(tokenParts.exp);

if (tokenParts.exp > now) {
return axiosInstance
Expand All @@ -66,16 +67,24 @@ axiosInstance.interceptors.response.use(
} else {
console.error('Refresh token is expired', tokenParts.exp, now);
localStorage.removeItem('username');
localStorage.removeItem('access_token');
localStorage.removeItem('refresh_token');
window.location.href = `/account/login/?next=${window.location.pathname}`;
}
} else {
console.error('Refresh token not available.');
localStorage.removeItem('username');
localStorage.removeItem('access_token');
localStorage.removeItem('refresh_token');
window.location.href = `/account/login/?next=${window.location.pathname}`;
}
}

// specific error handling done elsewhere
localStorage.removeItem('username');
localStorage.removeItem('access_token');
localStorage.removeItem('refresh_token');

return Promise.reject(error);
}
);
Expand Down
3 changes: 1 addition & 2 deletions mysite/frontend/src/components/Logout.js
Original file line number Diff line number Diff line change
Expand Up @@ -11,11 +11,10 @@ function handleLogout() {
localStorage.removeItem('refresh_token');
localStorage.removeItem('username');
axiosInstance.defaults.headers['Authorization'] = null;
console.log('Logout successful');
window.location.href = '/';
});
} catch (e) {
console.log(e);
console.error(e);
}
}

Expand Down
3 changes: 1 addition & 2 deletions mysite/frontend/src/components/errors/NetworkError.js
Original file line number Diff line number Diff line change
Expand Up @@ -53,11 +53,10 @@ class NetworkError extends Component {
axiosInstance
.get('/auth/hello/')
.then((response) => {
console.log('connect server successfully', response);
window.location.href = this.state.redirectURL;
})
.catch((err) => {
console.log('connect error', err);
console.error('connect error', err);
this.countDownMsgSet(newTimeout);
});
}
Expand Down
3 changes: 2 additions & 1 deletion mysite/frontend/src/components/game/GameEnd.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ import React, { Component } from 'react';
import { Button, Card, Col, Row } from 'react-bootstrap';
import { FontAwesomeIcon } from '@fortawesome/react-fontawesome';
import { faUserCog, faUser, faCrown } from '@fortawesome/free-solid-svg-icons';
import getUserName from '../../utils/getUserName';

class GameEnd extends Component {
constructor(props) {
Expand All @@ -19,7 +20,7 @@ class GameEnd extends Component {
}

render() {
const username = localStorage.getItem('username');
const username = this.props.username;
const adminName = this.props.roomData.admin;
const admin = adminName === username;

Expand Down
2 changes: 1 addition & 1 deletion mysite/frontend/src/components/game/GameOrganize.js
Original file line number Diff line number Diff line change
Expand Up @@ -52,7 +52,7 @@ class GameOrganize extends Component {
}

render() {
const username = localStorage.getItem('username');
const username = this.props.username;
const adminName = this.props.roomData.admin;
const admin = adminName === username;

Expand Down
Loading

0 comments on commit 1247590

Please sign in to comment.