feat: first version
Some checks failed
Build, check & Test / run (push) Failing after 39s

Signed-off-by: Florian BOUILLON <f.bouillon@aptatio.com>
This commit is contained in:
2023-07-20 17:41:16 +02:00
parent 2bd59f902f
commit 09ed4c487d
80 changed files with 1171 additions and 2755 deletions

View File

@ -1,79 +0,0 @@
import { objectOmit } from '@dzeio/object-util'
import mongoose from 'mongoose'
import type APIKey from '.'
import Client from '../Client'
import Dao from '../Dao'
export default class APIKeyDao extends Dao<APIKey> {
// @ts-expect-error typing fix
private model = mongoose.models['APIKey'] as null ?? mongoose.model('APIKey', new mongoose.Schema({
user: { type: String, required: true },
key: { type: String, required: true, unique: true, index: true},
permissions: [{ type: String }]
}, {
timestamps: true
}))
public async create(obj: Omit<APIKey, 'id' | 'created' | 'updated'>): Promise<APIKey | null> {
await Client.get()
return this.fromSource(await this.model.create(obj))
}
public async findAll(query?: Partial<APIKey> | undefined): Promise<APIKey[]> {
await Client.get()
try {
if (query?.id) {
const item = await this.model.findById(new mongoose.Types.ObjectId(query.id))
if (!item) {
return []
}
return [this.fromSource(item)]
}
const resp = await this.model.find(query ? this.toSource(query as APIKey) : {})
return resp.map(this.fromSource)
} catch (e) {
console.error(e)
return []
}
}
public async update(obj: APIKey): Promise<APIKey | null> {
await Client.get()
const query = await this.model.updateOne({
_id: new mongoose.Types.ObjectId(obj.id)
}, this.toSource(obj))
if (query.matchedCount >= 1) {
obj.updated = new Date()
return obj
}
return null
// return this.fromSource()
}
public async delete(obj: APIKey): Promise<boolean> {
await Client.get()
const res = await this.model.deleteOne({
_id: new mongoose.Types.ObjectId(obj.id)
})
return res.deletedCount > 0
}
private toSource(obj: APIKey): Omit<APIKey, 'id'> {
return objectOmit(obj, 'id', 'updated', 'created')
}
private fromSource(doc: mongoose.Document<any, any, APIKey>): APIKey {
return {
id: doc._id.toString(),
user: doc.get('user'),
key: doc.get('key'),
permissions: doc.get('permissions') ?? [],
updated: doc.get('updatedAt'),
created: doc.get('createdAt')
}
}
}

View File

@ -1,8 +0,0 @@
export default interface APIKey {
id: string
user: string
key: string
permissions: Array<string>
created: Date
updated: Date
}

View File

@ -1,18 +0,0 @@
import mongoose from 'mongoose'
export default class Client {
private static connectionString = import.meta.env.MONGODB
private static client = false
public static async get() {
if (!this.connectionString) {
throw new Error('Can\'t connect to the database, missing the connection string')
}
if (!this.client) {
console.log(this.connectionString)
mongoose.connect(this.connectionString)
this.client = true
}
return this.client
}
}

View File

@ -1,83 +0,0 @@
import { objectOmit } from '@dzeio/object-util'
import mongoose from 'mongoose'
import type Config from '.'
import Client from '../Client'
import Dao from '../Dao'
export default class ConfigDao extends Dao<Config> {
// @ts-expect-error typing fix
private model = mongoose.models['Config'] as null ?? mongoose.model('Config', new mongoose.Schema({
user: { type: String, required: true },
type: { type: String, required: true},
files: [{
name: { type: String, unique: true, required: true},
data: { type: Buffer, required: true }
}]
}, {
timestamps: true
}))
public async create(obj: Omit<Config, 'id' | 'created' | 'updated'>): Promise<Config | null> {
await Client.get()
return this.fromSource(await this.model.create(obj))
}
public async findAll(query?: Partial<Config> | undefined): Promise<Config[]> {
await Client.get()
try {
if (query?.id) {
const item = await this.model.findById(new mongoose.Types.ObjectId(query.id))
if (!item) {
return []
}
return [this.fromSource(item)]
}
const resp = await this.model.find(query ? this.toSource(query as Config) : {})
return resp.map(this.fromSource)
} catch (e) {
console.error(e)
return []
}
}
public async update(obj: Config): Promise<Config | null> {
await Client.get()
const query = await this.model.updateOne({
_id: new mongoose.Types.ObjectId(obj.id)
}, this.toSource(obj))
if (query.matchedCount >= 1) {
obj.updated = new Date()
return obj
}
return null
// return this.fromSource()
}
public async delete(obj: Config): Promise<boolean> {
await Client.get()
const res = await this.model.deleteOne({
_id: new mongoose.Types.ObjectId(obj.id)
})
return res.deletedCount > 0
}
private toSource(obj: Config): Omit<Config, 'id'> {
return objectOmit(obj, 'id', 'updated', 'created')
}
private fromSource(doc: mongoose.Document<any, any, Config>): Config {
return {
id: doc._id.toString(),
user: doc.get('user'),
type: doc.get('type'),
files: doc.get('files') ?? [],
updated: doc.get('updatedAt'),
created: doc.get('createdAt')
}
}
}

View File

@ -1,11 +0,0 @@
export default interface Config {
id: string
user: string
type: 'prusa'
files: Array<{
name: string
data: Buffer
}>
created: Date
updated: Date
}

View File

@ -1,8 +1,3 @@
import APIKeyDao from './APIKey/APIKeyDao'
import ConfigDao from './Config/ConfigDao'
import SessionDao from './Session/SessionDao'
import UserDao from './User/UserDao'
/**
* TODO:
* Add to `DaoItem` your model name
@ -15,10 +10,6 @@ import UserDao from './User/UserDao'
* Touch this interface to define which key is linked to which Dao
*/
interface DaoItem {
config: ConfigDao
user: UserDao
apiKey: APIKeyDao
session: SessionDao
}
/**
@ -57,10 +48,6 @@ export default class DaoFactory {
*/
private static initDao(item: keyof DaoItem): any | undefined {
switch (item) {
case 'config': return new ConfigDao()
case 'user': return new UserDao()
case 'apiKey': return new APIKeyDao()
case 'session': return new SessionDao()
default: return undefined
}
}

View File

@ -1,52 +0,0 @@
import jwt, { SignOptions } from 'jsonwebtoken'
import type Session from '.'
import CookieManager from '../../libs/CookieManager'
export interface SessionOptions {
cookieName: string
security: SignOptions
key?: string
privateKey?: string
publicKey?: string
}
export default class SessionDao {
private options: SessionOptions = {
cookieName: 'session',
security: {
algorithm: 'ES512'
},
privateKey: import.meta.env.PRIVATE_KEY ?? '',
publicKey: import.meta.env.PUBLIC_KEY ?? ''
}
public getSession(req: Request): Session | null {
const cookie = new CookieManager(req.headers.get('Cookie') ?? '').get(this.options.cookieName)
if (!cookie) {
return null
}
try {
return jwt.verify(cookie, (this.options.publicKey || this.options.key) as string) as Session
} catch {
return null
}
}
public setSession(session: Session, res: ResponseInit & { readonly headers: Headers; }) {
const token = jwt.sign(session, (this.options.privateKey || this.options.key) as string, this.options.security)
CookieManager.addCookie(res, {
key: this.options.cookieName,
value: token,
httpOnly: true,
path: '/',
secure: true,
sameSite: 'Strict',
maxAge: 365000
})
}
public removeSession(_res: ResponseInit & { readonly headers: Headers; }) {
}
}

View File

@ -1,3 +0,0 @@
export default interface Session {
userId: string
}

View File

@ -1,71 +0,0 @@
import { objectOmit } from '@dzeio/object-util'
import mongoose from 'mongoose'
import type User from '.'
import Client from '../Client'
import Dao from '../Dao'
export default class UserDao extends Dao<User> {
// @ts-expect-error typing fix
private model = mongoose.models['User'] as null ?? mongoose.model('User', new mongoose.Schema({
email: { type: String, required: true },
password: { type: String, required: true }
}, {
timestamps: true
}))
public async create(obj: Omit<User, 'id' | 'created' | 'updated'>): Promise<User | null> {
await Client.get()
return this.fromSource(await this.model.create(obj))
}
public async findAll(query?: Partial<User> | undefined): Promise<User[]> {
await Client.get()
if (query?.id) {
const item = await this.model.findById(new mongoose.Types.ObjectId(query.id))
if (!item) {
return []
}
return [this.fromSource(item)]
}
const resp = await this.model.find(query ? this.toSource(query as User) : {})
return resp.map(this.fromSource)
}
public async update(obj: User): Promise<User | null> {
await Client.get()
const query = await this.model.updateOne({
_id: new mongoose.Types.ObjectId(obj.id)
}, this.toSource(obj))
if (query.matchedCount >= 1) {
obj.updated = new Date()
return obj
}
return null
// return this.fromSource()
}
public async delete(obj: User): Promise<boolean> {
await Client.get()
const res = await this.model.deleteOne({
_id: new mongoose.Types.ObjectId(obj.id)
})
return res.deletedCount > 0
}
private toSource(obj: User): Omit<User, 'id'> {
return objectOmit(obj, 'id', 'updated', 'created')
}
private fromSource(doc: mongoose.Document<any, any, User>): User {
return {
id: doc._id.toString(),
email: doc.get('email'),
password: doc.get('password'),
updated: doc.get('updatedAt'),
created: doc.get('createdAt')
}
}
}

View File

@ -1,7 +0,0 @@
export default interface User {
id: string
email: string
password: string
created: Date
updated: Date
}