mirror of
https://github.com/Paris-est-Ludique/intranet.git
synced 2025-06-09 17:14:21 +02:00
Add generating anonymized db for new devs
This commit is contained in:
parent
aa76e33c54
commit
b3189e3bf4
5
.gitignore
vendored
5
.gitignore
vendored
@ -12,10 +12,7 @@ public/*
|
||||
!public/manifest.json
|
||||
|
||||
# Access
|
||||
access/gsheets.json
|
||||
access/jwt_secret.json
|
||||
access/db.json
|
||||
access/dbToLoad.json
|
||||
access/*
|
||||
|
||||
# Misc
|
||||
.DS_Store
|
||||
|
@ -3,35 +3,21 @@ import path from "path"
|
||||
import _ from "lodash"
|
||||
import { promises as fs, constants } from "fs"
|
||||
import { GoogleSpreadsheet, GoogleSpreadsheetWorksheet } from "google-spreadsheet"
|
||||
import { SheetNames, saveLocalDb, loadLocalDb } from "./localDb"
|
||||
|
||||
export { SheetNames } from "./localDb"
|
||||
|
||||
// Test write attack with: wget --header='Content-Type:application/json' --post-data='{"prenom":"Pierre","nom":"SCELLES","email":"test@gmail.com","telephone":"0601010101","dejaBenevole":false,"commentaire":""}' http://localhost:3000/PreVolunteerAdd
|
||||
|
||||
const CRED_PATH = path.resolve(process.cwd(), "access/gsheets.json")
|
||||
const DB_PATH = path.resolve(process.cwd(), "access/db.json")
|
||||
const DB_TO_LOAD_PATH = path.resolve(process.cwd(), "access/dbToLoad.json")
|
||||
|
||||
const REMOTE_UPDATE_DELAY = 40000
|
||||
const DELAY_AFTER_QUERY = 2000
|
||||
|
||||
let creds: string | undefined | null
|
||||
// eslint-disable-next-line @typescript-eslint/ban-types
|
||||
let states: { [sheetName in keyof SheetNames]?: object[] | undefined } = {}
|
||||
// eslint-disable-next-line @typescript-eslint/ban-types
|
||||
let types: { [sheetName in keyof SheetNames]?: object | undefined } = {}
|
||||
|
||||
export type ElementWithId<ElementNoId> = { id: number } & ElementNoId
|
||||
|
||||
export class SheetNames {
|
||||
JavGames = "Jeux JAV"
|
||||
|
||||
PreVolunteers = "PreMembres"
|
||||
|
||||
Teams = "Equipes"
|
||||
|
||||
Volunteers = "Membres"
|
||||
|
||||
Wishes = "Envies d'aider"
|
||||
}
|
||||
export const sheetNames = new SheetNames()
|
||||
|
||||
// eslint-disable-next-line @typescript-eslint/ban-types
|
||||
@ -55,7 +41,7 @@ export async function hasGSheetsAccess(): Promise<boolean> {
|
||||
|
||||
export async function checkGSheetsAccess(): Promise<void> {
|
||||
if (!(await hasGSheetsAccess())) {
|
||||
console.error(`Google Sheets: no creds found, loading local database ${DB_PATH} instead`)
|
||||
console.error(`Google Sheets: no creds found, loading local database instead`)
|
||||
}
|
||||
}
|
||||
export function getSheet<
|
||||
@ -126,7 +112,7 @@ export class Sheet<
|
||||
async setList(newState: Element[] | undefined): Promise<void> {
|
||||
this._state = JSON.parse(JSON.stringify(newState))
|
||||
this.modifiedSinceSave = true
|
||||
this.localDbSave()
|
||||
this.saveLocalDb()
|
||||
}
|
||||
|
||||
async nextId(): Promise<number> {
|
||||
@ -182,41 +168,16 @@ export class Sheet<
|
||||
this.dbLoad()
|
||||
}
|
||||
}
|
||||
if (__DEV__) {
|
||||
this.localDbSave()
|
||||
}
|
||||
}
|
||||
|
||||
async localDbSave(): Promise<void> {
|
||||
states[this.name] = this._state
|
||||
types[this.name] = this._type
|
||||
const toSave = { states, types }
|
||||
const jsonDB = __DEV__ ? JSON.stringify(toSave, null, 2) : JSON.stringify(toSave)
|
||||
await fs.writeFile(DB_PATH, jsonDB)
|
||||
async saveLocalDb(): Promise<void> {
|
||||
await saveLocalDb(this.name, this._state, this._type)
|
||||
}
|
||||
|
||||
async localDbLoad(): Promise<void> {
|
||||
if (_.isEmpty(states)) {
|
||||
let stringifiedDb
|
||||
try {
|
||||
stringifiedDb = await fs.readFile(DB_TO_LOAD_PATH)
|
||||
} catch {
|
||||
console.error(`No local database save found in ${DB_TO_LOAD_PATH}`)
|
||||
process.exit()
|
||||
}
|
||||
if (stringifiedDb) {
|
||||
const db = JSON.parse(stringifiedDb.toString())
|
||||
states = db.states
|
||||
types = db.types
|
||||
}
|
||||
}
|
||||
|
||||
if (!states[this.name]) {
|
||||
console.error(`Sheet ${this.name} couldn't be found in localDb`)
|
||||
process.exit()
|
||||
}
|
||||
this._state = states[this.name] as Element[]
|
||||
this._type = types[this.name] as Record<keyof Element, string>
|
||||
async loadLocalDb(): Promise<void> {
|
||||
const db = await loadLocalDb(this.name)
|
||||
this._state = db.state as Element[]
|
||||
this._type = db.type as Record<keyof Element, string>
|
||||
}
|
||||
|
||||
dbSave(): void {
|
||||
@ -250,10 +211,13 @@ export class Sheet<
|
||||
}
|
||||
|
||||
async dbFirstLoad(): Promise<void> {
|
||||
if (!(await hasGSheetsAccess()) && _.isEmpty(states)) {
|
||||
this.localDbLoad()
|
||||
if (!(await hasGSheetsAccess())) {
|
||||
await this.loadLocalDb()
|
||||
}
|
||||
this.dbLoad()
|
||||
if (__DEV__ && (await hasGSheetsAccess())) {
|
||||
this.saveLocalDb()
|
||||
}
|
||||
}
|
||||
|
||||
private async dbSaveAsync(): Promise<void> {
|
||||
|
299
src/server/gsheets/localDb.ts
Normal file
299
src/server/gsheets/localDb.ts
Normal file
@ -0,0 +1,299 @@
|
||||
// eslint-disable-next-line max-classes-per-file
|
||||
import path from "path"
|
||||
import _ from "lodash"
|
||||
import { promises as fs } from "fs"
|
||||
import { Volunteer } from "../../services/volunteers"
|
||||
import { PreVolunteer } from "../../services/preVolunteers"
|
||||
|
||||
const DB_PATH = path.resolve(process.cwd(), "access/db.json")
|
||||
const DB_TO_LOAD_PATH = path.resolve(process.cwd(), "access/dbToLoad.json")
|
||||
const ANONYMIZED_DB_PATH = path.resolve(process.cwd(), "access/dbAnonymized.json")
|
||||
|
||||
export class SheetNames {
|
||||
JavGames = "Jeux JAV"
|
||||
|
||||
PreVolunteers = "PreMembres"
|
||||
|
||||
Teams = "Equipes"
|
||||
|
||||
Volunteers = "Membres"
|
||||
|
||||
Wishes = "Envies d'aider"
|
||||
}
|
||||
|
||||
// eslint-disable-next-line @typescript-eslint/ban-types
|
||||
type States = { [sheetName in keyof SheetNames]?: object[] | undefined }
|
||||
let states: States = {}
|
||||
// eslint-disable-next-line @typescript-eslint/ban-types
|
||||
type Types = { [sheetName in keyof SheetNames]?: object | undefined }
|
||||
let types: Types = {}
|
||||
|
||||
export async function saveLocalDb(
|
||||
name: keyof SheetNames,
|
||||
// eslint-disable-next-line @typescript-eslint/ban-types
|
||||
state: object[] | undefined,
|
||||
// eslint-disable-next-line @typescript-eslint/ban-types
|
||||
type: object | undefined
|
||||
): Promise<void> {
|
||||
states[name] = state
|
||||
types[name] = type
|
||||
const toSave = { states, types }
|
||||
const jsonDB = __DEV__ ? JSON.stringify(toSave, null, 2) : JSON.stringify(toSave)
|
||||
await fs.writeFile(DB_PATH, jsonDB)
|
||||
|
||||
toSave.states = anonimizedDb(toSave.states)
|
||||
const jsonAnonimizedDB = __DEV__ ? JSON.stringify(toSave, null, 2) : JSON.stringify(toSave)
|
||||
await fs.writeFile(ANONYMIZED_DB_PATH, jsonAnonimizedDB)
|
||||
}
|
||||
|
||||
export async function loadLocalDb(
|
||||
name: keyof SheetNames
|
||||
// eslint-disable-next-line @typescript-eslint/ban-types
|
||||
): Promise<{ state: object[]; type: object }> {
|
||||
if (_.isEmpty(states)) {
|
||||
let stringifiedDb
|
||||
try {
|
||||
stringifiedDb = await fs.readFile(DB_TO_LOAD_PATH)
|
||||
} catch {
|
||||
console.error(`No local database save found in ${DB_TO_LOAD_PATH}`)
|
||||
process.exit()
|
||||
}
|
||||
if (stringifiedDb) {
|
||||
const db = JSON.parse(stringifiedDb.toString())
|
||||
states = db.states
|
||||
types = db.types
|
||||
}
|
||||
}
|
||||
|
||||
if (!states[name]) {
|
||||
console.error(`Sheet ${name} couldn't be found in localDb`)
|
||||
process.exit()
|
||||
}
|
||||
return {
|
||||
state: states[name] as Element[],
|
||||
type: types[name] as Record<keyof Element, string>,
|
||||
}
|
||||
}
|
||||
|
||||
export function isDbLoaded(): boolean {
|
||||
return !_.isEmpty(states)
|
||||
}
|
||||
|
||||
const fakeFirstnames = [
|
||||
"Suzanne",
|
||||
"Louis",
|
||||
"Madeleine",
|
||||
"Paul",
|
||||
"Alain",
|
||||
"Sylvie",
|
||||
"Pierre",
|
||||
"Daniel",
|
||||
"Jacques",
|
||||
"Martine",
|
||||
"Anne",
|
||||
"Bernard",
|
||||
"Claude",
|
||||
"Louise",
|
||||
"René",
|
||||
"Jacqueline",
|
||||
"Françoise",
|
||||
"Christian",
|
||||
"Nathalie",
|
||||
"Nicole",
|
||||
"Isabelle",
|
||||
"Monique",
|
||||
"Denise",
|
||||
"Marie",
|
||||
"Jeanne",
|
||||
"Georges",
|
||||
"Christine",
|
||||
"Nicolas",
|
||||
"Michel",
|
||||
"Christiane",
|
||||
"Jean",
|
||||
"Marcel",
|
||||
"Marguerite",
|
||||
"André",
|
||||
"Hélène",
|
||||
"Henri",
|
||||
"Roger",
|
||||
"Catherine",
|
||||
"Philippe",
|
||||
"Robert",
|
||||
]
|
||||
const fakeLastnames = [
|
||||
"Bernard",
|
||||
"Robert",
|
||||
"Guerin",
|
||||
"Joly",
|
||||
"Dumont",
|
||||
"Robin",
|
||||
"Vincent",
|
||||
"Perrin",
|
||||
"Picard",
|
||||
"Lefevre",
|
||||
"Roy",
|
||||
"Martin",
|
||||
"Barbier",
|
||||
"Clement",
|
||||
"Lucas",
|
||||
"Gauthier",
|
||||
"Duval",
|
||||
"Bertrand",
|
||||
"Roux",
|
||||
"Girard",
|
||||
"Dupont",
|
||||
"Leroy",
|
||||
"Dufour",
|
||||
"Muller",
|
||||
"Martinez",
|
||||
"Thomas",
|
||||
"Durand",
|
||||
"Dubois",
|
||||
"Marie",
|
||||
"Marchand",
|
||||
"Lefebvre",
|
||||
"Brun",
|
||||
"Bonnet",
|
||||
"Moreau",
|
||||
"Francois",
|
||||
"Gerard",
|
||||
"Rousseau",
|
||||
"Faure",
|
||||
"Renard",
|
||||
"Meunier",
|
||||
"David",
|
||||
"Giraud",
|
||||
"Simon",
|
||||
"Vidal",
|
||||
"Fournier",
|
||||
"Arnaud",
|
||||
"Blanchard",
|
||||
"Colin",
|
||||
"Meyer",
|
||||
"Leroux",
|
||||
"Lemaire",
|
||||
"Mercier",
|
||||
"Garnier",
|
||||
"Morin",
|
||||
"Lambert",
|
||||
"Fontaine",
|
||||
"Morel",
|
||||
"Michel",
|
||||
"Blanc",
|
||||
"Denis",
|
||||
"Noel",
|
||||
"Roussel",
|
||||
"Riviere",
|
||||
"Garcia",
|
||||
"Schmitt",
|
||||
"Chevalier",
|
||||
"Mathieu",
|
||||
"Petit",
|
||||
"Gautier",
|
||||
"Gaillard",
|
||||
"Legrand",
|
||||
"Henry",
|
||||
"Laurent",
|
||||
"Caron",
|
||||
"Andre",
|
||||
"Masson",
|
||||
"Nicolas",
|
||||
"Roche",
|
||||
"Richard",
|
||||
"Brunet",
|
||||
"Boyer",
|
||||
]
|
||||
const fakeEmailDomains = [
|
||||
"yahoo.fr",
|
||||
"gmail.com",
|
||||
"gmail.com",
|
||||
"gmail.com",
|
||||
"gmail.com",
|
||||
"gmail.com",
|
||||
"gmail.com",
|
||||
"noos.fr",
|
||||
"hotmail.com",
|
||||
"hotmail.com",
|
||||
"hotmail.com",
|
||||
"live.fr",
|
||||
"hotmail.fr",
|
||||
"wanadoo.fr",
|
||||
"free.fr",
|
||||
"yahoo.com",
|
||||
"laposte.net",
|
||||
"outlook.com",
|
||||
"gmail",
|
||||
"mailoo.org",
|
||||
"padaone.fr",
|
||||
"orange.fr",
|
||||
"netcourrier.com",
|
||||
"neuf.fr",
|
||||
"poptalks.com",
|
||||
"GMAIL.COM",
|
||||
"wethinkcode.co.za",
|
||||
"aliceadsl.fr",
|
||||
"inextenso.fr",
|
||||
"aol.com",
|
||||
"epitech.eu",
|
||||
"me.com",
|
||||
"sncf.fr",
|
||||
"outlook.fr",
|
||||
"paris.fr",
|
||||
"sfr.fr",
|
||||
"lilo.org",
|
||||
"protonmail.com",
|
||||
"posteo.net",
|
||||
"msn.com",
|
||||
"mailo.org",
|
||||
"live.com",
|
||||
]
|
||||
|
||||
function anonimizedDb(_s: States): States {
|
||||
const s = _.cloneDeep(_s)
|
||||
if (s.Volunteers) {
|
||||
;(s.Volunteers as Volunteer[]).forEach((v) => {
|
||||
v.firstname = fakeFirstnames[numberToRand(v.id) % fakeFirstnames.length]
|
||||
v.lastname = fakeLastnames[numberToRand(v.id) % fakeLastnames.length]
|
||||
const fakeEmailDomain = fakeEmailDomains[numberToRand(v.id) % fakeEmailDomains.length]
|
||||
v.email = `${v.firstname}.${v.lastname}.${v.id}@${fakeEmailDomain}`.toLowerCase()
|
||||
const mobileStart = v.mobile.match(/^\+?[0-9][0-9]/)
|
||||
const mobileEnd = [1, 2, 3, 4]
|
||||
.map((n) => `${numberToRand(v.id + n) % 10}${numberToRand(v.id + n + 10) % 10}`)
|
||||
.join(" ")
|
||||
v.mobile = v.mobile ? `${(mobileStart || ["06"])[0]} ${mobileEnd}` : ""
|
||||
v.photo = `${v.firstname}_${v.lastname}.jpg`.toLowerCase()
|
||||
v.password1 = "$2y$1a$Kt/FAKEFAKEFAKEFAKEc6.FAKEFAKEFAKEFAKE//FAKEFAKEFAKEy"
|
||||
v.password2 = "$2y$1a$Kt/FAKEFAKEFAKEFAKEc6.FAKEFAKEFAKEFAKE//FAKEFAKEFAKEy"
|
||||
v.acceptsNotifs = ""
|
||||
if (v.id % 13 === 0) {
|
||||
v.acceptsNotifs = "oui"
|
||||
} else if (v.id % 251 === 0) {
|
||||
v.acceptsNotifs = "non"
|
||||
}
|
||||
v.pushNotifSubscription =
|
||||
v.id % 13 === 0
|
||||
? '{"endpoint":"https://fcm.googleapis.com/fcm/send/f-EAfakedfakedU:APA91fakedfakedzIk-DEglfakedfaked9ugI--ljtfakedfakedfakedfakedfakedfakedP3t-ggU7Afakedfakedfakedkai","expirationTime":null,"keys":{"p256dh":"BEZOJSfakedfakedfakedfakedfakedfakedfakedfakedfakedfakedgYs-cafakedw","auth":"GlMfakedfakedFRg"}}'
|
||||
: ""
|
||||
})
|
||||
}
|
||||
if (s.PreVolunteers) {
|
||||
;(s.PreVolunteers as PreVolunteer[]).forEach((v) => {
|
||||
v.firstname = fakeFirstnames[numberToRand(v.id) % fakeFirstnames.length]
|
||||
v.lastname = fakeLastnames[numberToRand(v.id) % fakeLastnames.length]
|
||||
const fakeEmailDomain = fakeEmailDomains[numberToRand(v.id) % fakeEmailDomains.length]
|
||||
v.email = `${v.firstname}.${v.lastname}.${v.id}@${fakeEmailDomain}`.toLowerCase()
|
||||
const mobileStart = v.mobile.match(/^\+?[0-9][0-9]/)
|
||||
const mobileEnd = [1, 2, 3, 4]
|
||||
.map((n) => `${numberToRand(v.id + n) % 10}${numberToRand(v.id + n + 10) % 10}`)
|
||||
.join(" ")
|
||||
v.mobile = v.mobile ? `${(mobileStart || ["06"])[0]} ${mobileEnd}` : ""
|
||||
v.comment = v.id % 3 === 0 ? "Bonjour, j'adore l'initiative!" : ""
|
||||
})
|
||||
}
|
||||
return s
|
||||
}
|
||||
|
||||
function numberToRand(n: number) {
|
||||
return (1664525 * n + 1013904223) % 512
|
||||
}
|
Loading…
x
Reference in New Issue
Block a user