import mongooseUniqueValidator from "mongoose-unique-validator"; import {AppMaster} from "@onebro/appmaster"; import { DeepPartial, IModelCreator, IStatus, IQuery, mapSelectedData, ILocation, getSchemaRefs, ObjectId, encrypt, decrypt} from "@onebro/oba-common"; import { OBAuthAcctRoles, OBAuthAcctConfig, OBAuthAcctModel, OBAuthAcct, OBAuthAcctJson, OBAuthAcctStatus, OBAuthAcctStatuses as statuses,} from "../types"; import {obAuthAcctSchema as acct} from "../schemas"; const refs = getSchemaRefs(acct); const ekey = process.env.OBA_API_EKEY; export const obAuthAcctModels:IModelCreator = async m => { acct.plugin(mongooseUniqueValidator); acct.virtual("lastStatus").get(function(){return this.status?(this.status[this.status.length - 1] as any).json(statuses):null;}); acct.virtual("lastStatus").set(function(o:IStatus){this.status = [...this.status,o];}); acct.virtual("statusStr").get(function(){return this.lastStatus?this.lastStatus.name + " @ " + this.lastStatus.time:"";}); acct.virtual("fullname").get(function(){return this.name?this.name.first + " " +this.name.last:"";}); acct.virtual("age").get(function(){ const earliest = new Date(this.dob || "01/01/"+this.yob); const ageInMS = new Date().getTime() - new Date(earliest).getTime(); const ageInYrs = ageInMS?Math.floor(ageInMS/(1000 * 60 * 60 * 24 * 365.25)):0; return [ageInYrs - 1,ageInYrs] as [ number,number];}); acct.virtual("hasPhn").get(function(){return !!this.phn;}); acct.virtual("hasAuthed").get(function(){return !!this.status.find((s:IStatus) => s.name == "A");}); acct.virtual("location").get(function(){ const loc = this.locs[this.locs.length - 1]; return loc?loc.info:null;}); acct.virtual("location").set(function(o:ILocation){this.locs = [...this.locs,o];}); acct.statics._populate = async function(o?:OBAuthAcct){ await o.populate(refs).execPopulate(); return o;}; acct.statics._find = async function(o:Partial|string){ if(!o) return m.e.badinfo(); const p = typeof o == "string"? await OBAuthAcct.findById(o): await OBAuthAcct.findOne(OBAuthAcct.translateAliases(o)); if(!p) throw m.e.doesNotExist("account"); return p;}; acct.statics._create = async function(o:OBAuthAcctConfig){return new OBAuthAcct({ ...o, ...(o.user?{user:encrypt(ekey,JSON.stringify(o.user))}:null), scopes:[{name:m.vars.name,version:m.vars.version + ""}],});}; acct.statics._update = async function(o:OBAuthAcct,p:DeepPartial){ if(p.user){p.user = encrypt(ekey,JSON.stringify(o.user));} await o.set(p).save(); return await OBAuthAcct._populate(o);}; acct.statics._remove = async function(o:OBAuthAcct){return await o.remove().then(() => ({removed:o._id}));}; acct.statics._query = async function(o:IQuery){ const {query,populate,limit,skip,sort,select} = o; const results:OBAuthAcct[] = await this.find(this.translateAliases(query)) .populate(populate) //.where(where) .limit(limit) .skip(skip) .sort(sort) .exec(); const accts = mapSelectedData(select,results); return {accts};}; acct.methods.valid = async function(){ const status = this.lastStatus.name.toLocaleLowerCase(); const badStatus = ["locked","deleted","disabled",].includes(status); if(badStatus) throw m.e.unauthorized("user"); return this;}; acct.methods.json = function(){ const { id,created,updated,lastStatus:status,statusStr, fullname:name,age,role,scopes, contact:{phn},location,user,info} = this as OBAuthAcct; const json:OBAuthAcctJson = { id,created,updated,status,statusStr, role:OBAuthAcctRoles[role], scopes:scopes.map(s => s.name), name,age,location,phnEnabled:!!phn, memberSince:new Date(created),info, ...(user?{user:JSON.parse(decrypt(ekey,user))}:null),}; return json;}; const OBAuthAcct = m.db.model("onebrother","OBAuthAcct",acct); await OBAuthAcct.init(); return {OBAuthAcct}; };