UNPKG

dimensions-ai

Version:

A generalized AI Competition framework that allows you to create any competition you want in any language you want with no hassle.

250 lines 9.66 kB
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) { function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); } return new (P || (P = Promise))(function (resolve, reject) { function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } } function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } } function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); } step((generator = generator.apply(thisArg, _arguments || [])).next()); }); }; import admin from 'firebase-admin'; import { Plugin } from '../../Plugin'; import { Database } from '../../Plugin/Database'; import { DatabaseType } from '../../Dimension'; import { pickMatch } from '../../Station/routes/api/dimensions/match'; import bcrypt from 'bcryptjs'; import { generateToken, verify } from '../../Plugin/Database/utils'; import { Player } from '../../Tournament'; import { deepMerge } from '../../utils/DeepMerge'; import { deepCopy } from '../../utils/DeepCopy'; // eslint-disable-next-line @typescript-eslint/no-var-requires require('dotenv').config(); const salt = bcrypt.genSaltSync(); export class FireStore extends Database { constructor(fireStoreConfigs, configs = {}) { super(configs); this.name = 'FireStore'; this.type = Plugin.Type.DATABASE; admin.initializeApp({ credential: admin.credential.cert(fireStoreConfigs.keyFile), }); } /** * Connects to the firestore database and returns the db object */ connect() { return __awaiter(this, void 0, void 0, function* () { this.db = admin.firestore(); this.db.settings({ ignoreUndefinedProperties: true }); return this.db; }); } initialize() { return __awaiter(this, void 0, void 0, function* () { yield this.connect(); this.userCollection = this.db.collection(FireStore.Collections.USERS); this.matchesCollection = this.db.collection(FireStore.Collections.MATCHES); this.tournamentConfigsCollection = this.db.collection(FireStore.Collections.TOURNAMENT_CONFIGS); // create admin user const existingUser = yield this.getUser('admin'); if (!existingUser) { yield this.registerUser('admin', process.env.ADMIN_PASSWORD); } return; }); } storeMatch(match, governID) { return __awaiter(this, void 0, void 0, function* () { const data = Object.assign(Object.assign({}, pickMatch(match)), { governID: governID }); // remove extra data delete data.configs; // store all relevant data const plainAgentIDtoTournamentID = {}; data.mapAgentIDtoTournamentID.forEach((val, key) => { plainAgentIDtoTournamentID[key] = val; }); data.mapAgentIDtoTournamentID = plainAgentIDtoTournamentID; return this.matchesCollection.doc().set(data); }); } getMatch(id) { return __awaiter(this, void 0, void 0, function* () { const snapshot = yield this.matchesCollection .where('matchID', '==', id) .get(); return snapshot.docs[0].data(); }); } getPlayerMatches(playerID, governID, offset = 0, limit = 10, order = -1) { return __awaiter(this, void 0, void 0, function* () { let sortOrder = 'desc'; if (order > 0) { sortOrder = 'asc'; } let query = this.matchesCollection .where('governID', '==', governID) .orderBy('creationDate', sortOrder) .offset(offset); if (limit == 0) { return []; } if (limit > 0) { query = query.limit(limit); } const snapshot = yield query.get(); // eslint-disable-next-line @typescript-eslint/ban-ts-comment // @ts-ignore return snapshot.docs.map((d) => d.data()); }); } registerUser(username, password, // eslint-disable-next-line @typescript-eslint/explicit-module-boundary-types userData) { return __awaiter(this, void 0, void 0, function* () { const hash = bcrypt.hashSync(password, salt); return this.userCollection.doc(username).set({ username: username, passwordHash: hash, statistics: {}, playerID: Player.generatePlayerID(), meta: Object.assign({}, userData), }); }); } /** * Gets user information. If public is false, will retrieve all information other than password * @param usernameOrID */ getUser(usernameOrID, publicView = true) { return __awaiter(this, void 0, void 0, function* () { const doc = yield this.getUserDoc(usernameOrID); if (doc === null) { return null; } const user = doc.data(); if (user && publicView) { user.passwordHash = ''; } return user; }); } getUserDoc(usernameOrID) { return __awaiter(this, void 0, void 0, function* () { let snapshot = yield this.userCollection .where('playerID', '==', usernameOrID) .get(); if (snapshot.empty) { snapshot = yield this.userCollection .where('username', '==', usernameOrID) .get(); } if (snapshot.empty) { return null; } return snapshot.docs[0]; }); } loginUser(username, password) { return __awaiter(this, void 0, void 0, function* () { const snapshot = yield this.userCollection .where('username', '==', username) .get(); if (snapshot.empty) { throw new Error('Not a valid user'); } const user = snapshot.docs[0].data(); if (bcrypt.compareSync(password, user.passwordHash)) { return generateToken(user); } else { throw new Error('Invalid password'); } }); } updateUser(usernameOrID, update) { return __awaiter(this, void 0, void 0, function* () { const doc = yield this.getUserDoc(usernameOrID); if (doc === null) { throw new Error('Not a valid user'); } yield doc.ref.update(update); return deepMerge(deepCopy(doc.data()), deepCopy(update)); }); } deleteUser(usernameOrID) { return __awaiter(this, void 0, void 0, function* () { const doc = yield this.getUserDoc(usernameOrID); yield doc.ref.delete(); }); } verifyToken(jwt) { return __awaiter(this, void 0, void 0, function* () { return verify(jwt); }); } isAdmin(user) { if (user.username === 'admin') return true; return false; } getUsersInTournament(tournamentKey, offset = 0, limit = -1) { return __awaiter(this, void 0, void 0, function* () { const key = `statistics.${tournamentKey}`; if (limit == 0) { return []; } let query = this.userCollection .where(`${key}.matchesPlayed`, '>=', 0) .offset(offset); if (limit > 0) { query = query.limit(limit); } const snapshot = yield query.get(); return snapshot.docs.map((d) => d.data()); }); } manipulate(dimension) { return __awaiter(this, void 0, void 0, function* () { dimension.configs.backingDatabase = DatabaseType.FIRESTORE; return; }); } storeTournamentConfigs(tournamentID, tournamentConfigs, status) { return __awaiter(this, void 0, void 0, function* () { yield this.tournamentConfigsCollection.doc(tournamentID).set({ status: status, configs: tournamentConfigs, modificationDate: new Date(), }); return; }); } getTournamentConfigsModificationDate(tournamentID) { return __awaiter(this, void 0, void 0, function* () { const snapshot = yield this.tournamentConfigsCollection .doc(tournamentID) .get(); if (snapshot.exists) { return new Date(snapshot.data().modificationDate); } return null; }); } getTournamentConfigs(tournamentID) { return __awaiter(this, void 0, void 0, function* () { const snapshot = yield this.tournamentConfigsCollection .doc(tournamentID) .get(); return snapshot.data(); }); } } (function (FireStore) { let Collections; (function (Collections) { Collections["MATCHES"] = "d_matches"; Collections["USERS"] = "d_users"; Collections["TOURNAMENT_CONFIGS"] = "d_tourney_configs"; })(Collections = FireStore.Collections || (FireStore.Collections = {})); })(FireStore || (FireStore = {})); //# sourceMappingURL=index.js.map