Skip to content

Commit

Permalink
wip - clan cherry-pick
Browse files Browse the repository at this point in the history
  • Loading branch information
fcaps committed Nov 22, 2023
1 parent 0a42c9e commit 62e6478
Show file tree
Hide file tree
Showing 28 changed files with 948 additions and 1,408 deletions.
35 changes: 35 additions & 0 deletions .env.faf-xyz
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
# node env is set statically to "development" in the dockerfile, you could override it here.
#NODE_ENV=production

# you should not need to change the port (used by express) inside the container, just here for completion
#PORT=3000

# configs to change the ports in docker compose for the container
# only needed if your host already has 8020 binded to another service
# beware, changing the host port (8020) also needs an update in the hydra client for valid callback-urls
#WEBSITE_EXPOSED_PORT=8020
#WEBSITE_CONTAINER_PORT=3000

HOST=http://localhost:8020
API_URL=https://api.faforever.xyz
OAUTH_URL=https://hydra.faforever.xyz

# on a local environment with docker, the internal docker-service-domain (faf-ory-hydra:4444) is not reachable for a browser
# you can omit this env and it will fallback to OAUTH_URL if you know what you are doing.
#OAUTH_PUBLIC_URL=http://localhost:4444

# unsing the "production" wordpress because the faf-local-stack is just an empty instance without any news etc.
WP_URL=https://direct.faforever.com

OAUTH_CLIENT_ID=faf-website
OAUTH_CLIENT_SECRET=banana
SESSION_SECRET_KEY=bananaa
RECAPTCHA_SITE_KEY=6LeIxAcTAAAAAJcZVRqyHh71UMIEGNQ_MXjiZKhI
# JAVA-API token lifetime in seconds
TOKEN_LIFESPAN=43200
CLAN_INVITES_LIFESPAN_DAYS=30
# Interval for the extractor.js in minutes
EXTRACTOR_INTERVAL=5
# Interval for the getRecentUsers.js in seconds
PLAYER_COUNT_INTERVAL=15

18 changes: 18 additions & 0 deletions lib/ApiErrors.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
class JavaApiError extends Error
{
constructor(status, url, errors) {
super('Failed request "' + url + '" with status "' + status + '"')

this.status = status
this.url = url
this.errors = errors
}

}

class GenericJavaApiError extends Error
{
}

module.exports.JavaApiError = JavaApiError
module.exports.GenericJavaApiError = GenericJavaApiError
116 changes: 116 additions & 0 deletions lib/clan/ClanRepository.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,116 @@
const {JavaApiError, GenericJavaApiError} = require("../ApiErrors");

class ClanRepository {
constructor(javaApiClient, monthsInThePast = 12) {
this.javaApiClient = javaApiClient
this.monthsInThePast = monthsInThePast
}

getUpdateTimeForApiEntries() {
const date = new Date();
date.setMonth(date.getMonth() - this.monthsInThePast);

return date.toISOString()
}

async updateClan(id, name, description, tag) {
const newClanObject = {
"data": {
"type": "clan",
"id": id,
"attributes": {
"description": description,
"name": name,
"tag": tag
}
}
};

try {
const response = await this.javaApiClient.patch(`/data/clan/${id}`, newClanObject)

if (response.status !== 200) {
throw new Error('ClanRepository::fetchClanMembership failed with response status "' + response.status + '"')
}

return this.mapClanMembership(JSON.parse(response.data))
} catch (e) {
if (e.response && e.response.data?.errors) {
throw new JavaApiError(e.response.status, `patch /data/clan/${id}`, e.response.data.errors)
}

throw GenericJavaApiError('ClanRepository::fetchClanMembership failed')
}



}

async fetchClanMembership(clanMembershipId) {
let response = await this.javaApiClient.get(`/data/clanMembership/${clanMembershipId}/clan?include=memberships.player&fields[clan]=createTime,description,name,tag,updateTime,websiteUrl,founder,leader&fields[player]=login,updateTime&fields[clanMembership]=createTime,player`,)

if (response.status !== 200) {
throw new Error('ClanRepository::fetchClanMembership failed with response status "' + response.status + '"')
}

return this.mapClanMembership(JSON.parse(response.data))
}

mapClanMembership(data) {
if (typeof data !== 'object' || data === null) {
throw new Error('ClanRepository::mapClanMembership malformed response, not an object')
}

if (!data.hasOwnProperty('data')) {
throw new Error('ClanRepository::mapClanMembership malformed response, expected "data"')
}

if (typeof data.data !== 'object' || data.data === null) {
return null
}

if (typeof data.included !== 'object' || data.included === null) {
throw new Error('ClanRepository::mapClanMembership malformed response, expected "included"')
}

const clanMembershipRaw = data.data.attributes


const clanMembership = {
clan_id: data.data.id,
clan_name: clanMembershipRaw.name,
clan_tag: clanMembershipRaw.tag,
clan_description: clanMembershipRaw.description,
clan_create_time: clanMembershipRaw.createTime,
}

let members = {};

for (let k in data.included) {
switch (data.included[k].type) {
case "player":
const player = data.included[k];
if (!members[player.id]) members[player.id] = {};
members[player.id].id = player.id;
members[player.id].name = player.attributes.login;

break;

case "clanMembership":
const membership = data.included[k];
const member = membership.relationships.player.data;
if (!members[member.id]) members[member.id] = {};
members[member.id].id = member.id;
members[member.id].membershipId = membership.id;
members[member.id].joinedAt = membership.attributes.createTime;
break;
}
}

clanMembership.members = members

return clanMembership
}
}

module.exports = ClanRepository
1 change: 0 additions & 1 deletion public/js/app/clans.js
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,6 @@ function clanUpdate() {
for (clanIndex; clanIndex < next100Players; clanIndex++) {
if (clanIndex < 0) {
clanIndex = 0;
console.log('There are no more players left.');
}
// Gets the player data and inserts it into the li element

Expand Down
72 changes: 0 additions & 72 deletions public/js/app/getClans.js

This file was deleted.

1 change: 1 addition & 0 deletions public/js/app/members/test.json~
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
{"data":{"type":"clan","id":"2354","attributes":{"createTime":"2023-11-10T23:16:32Z","description":"asdasd","name":"asd","tag":"asd","updateTime":"2023-11-10T23:16:32Z","websiteUrl":"http://localhost:8096/clan/2354"},"relationships":{"founder":{"data":{"type":"player","id":"7"}},"leader":{"data":{"type":"player","id":"7"}}}},"included":[{"type":"clanMembership","id":"15594","attributes":{"createTime":"2023-11-10T23:16:32Z"},"relationships":{"player":{"data":{"type":"player","id":"7"}}}},{"type":"player","id":"7","attributes":{"login":"steambie","updateTime":"2023-10-27T10:38:46Z"}}]}
9 changes: 0 additions & 9 deletions public/styles/site/clans.sass
Original file line number Diff line number Diff line change
Expand Up @@ -178,15 +178,6 @@ input
textarea
width: 40vw

.clanManagementDanger
background-color: variables.$Cybran-dark
border-radius: 20px
ul
text-align: center
li
display: inline-block
list-style: none
text-align: left
.clanManagementTable
padding: 1.5em
display: inline-block
Expand Down
31 changes: 30 additions & 1 deletion routes/views/account/post/error.js
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
const {validationResult} = require('express-validator');

module.exports = {
parseApiErrors: function (body, flash) {
let errorMessages = [];
Expand All @@ -17,5 +19,32 @@ module.exports = {
flash.class = 'alert-danger';
flash.messages = errorMessages;
flash.type = 'Error!';
}
},
errorChecking: (req, res, path) => {
let flash = {}
let errorArray = [];
//We are putting a space in our forEach so that the errors comma don't stick to the next error.
validationResult(req).errors.forEach(error => errorArray.push(` ${error.msg}`));
flash.class = 'alert-danger';
flash.messages = errorArray;
flash.type = 'Error!';
res.render(path, {flash: flash});
},
userUpdate: (req, res, path) => {
axios.get(`${process.env.API_URL}/me`, {
headers: {
'Authorization': `Bearer ${req.user.token}`,
}
}).then(response => {
let user = response.data;
user.token = req.user.token;
user.data.id = user.data.attributes.userId;
req.logIn(user, function (err) {
if (err) console.error(err);
res.redirect(path);
});
}).catch(e => {
console.log('error updating user')
});
}
}
25 changes: 21 additions & 4 deletions routes/views/clanRouter.js
Original file line number Diff line number Diff line change
@@ -1,7 +1,24 @@
const express = require('express');
const router = express.Router();
const express = require('express')
const router = express.Router()
const middlewares = require('../middleware')

// This will be replaced soon, therefor I did not spend time on it
router.get('*', (req, res) => res.status(503).render('errors/503-known-issue'));
router.get('/create', middlewares.isAuthenticated(), require('clans/get/create'))
router.get('/manage', middlewares.isAuthenticated(), require('clans/get/manage'))
router.get('/accept_invite', middlewares.isAuthenticated(), require('clans/get/accept_invite'))
router.post('/create', middlewares.isAuthenticated(), require('clans/post/create'))
router.post('/destroy', middlewares.isAuthenticated(), require('clans/post/destroy'))
router.post('/invite', middlewares.isAuthenticated(), require('clans/post/invite'))
router.post('/kick', middlewares.isAuthenticated(), require('clans/post/kick'))
router.post('/transfer', middlewares.isAuthenticated(), require('clans/post/transfer'))
router.post('/update', middlewares.isAuthenticated(), require('clans/post/update'))
router.post('/leave', middlewares.isAuthenticated(), require('clans/post/leave'))
router.post('/join', middlewares.isAuthenticated(), require('clans/post/join'))

router.get('/', require('clans/get/clans'))
router.get('/getClan', require('clans/get/getClan'))
router.get('/*', (req, res) => {
let id = req.path.slice(-3)
res.redirect(`/clans/getClan?tag=${id}`)
})

module.exports = router
29 changes: 29 additions & 0 deletions routes/views/clans/get/clans.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
exports = module.exports = function (req, res) {
let flash = {};
if (req.query.flash) {

flash.class = 'alert-success';
flash.type = 'Success!';
switch (req.query.flash) {
case 'leave':
flash.messages = 'You left your clan.';
break;

case 'destroy':
flash.messages = 'You deleted your clan.';
break;

case 'transfer':
flash.messages = `You have transferred your clan to ${req.query.newLeader}.`;
break;

case 'error':
flash.class = 'alert-danger';
flash.messages = 'There was an issue with your request.';
flash.type = 'Error!';
break;
}
}
res.render('clans', {flash: flash});

};
Loading

0 comments on commit 62e6478

Please sign in to comment.