UNPKG

@cocreate/organizations

Version:

A simple organizations component in vanilla javascript. Easily configured using HTML5 attributes and/or JavaScript API.

253 lines (215 loc) 8.41 kB
import Crud from '@cocreate/crud-client'; import Action from '@cocreate/actions'; import Elements from '@cocreate/elements'; import Config from '@cocreate/config'; import Indexeddb from '@cocreate/indexeddb'; import uuid from '@cocreate/uuid'; async function generateDB(organization = { object: {} }, user = { object: {} }) { const organization_id = organization.object._id || Crud.ObjectId().toString(); const apikey = organization.object.key || uuid.generate(); const user_id = user.object._id || Crud.ObjectId().toString(); try { // Create organization organization.method = 'object.create' organization.storage = 'indexeddb' organization.database = organization_id organization.array = 'organizations' organization.object._id = organization_id organization.object.name = organization.object.name || 'untitiled' organization.organization_id = organization_id Indexeddb.send(organization); // Create user user.method = 'object.create' user.storage = 'indexeddb' user.database = organization_id user.array = 'users' user.object._id = user_id user.object.firstname = user.object.firstname || 'untitiled' user.object.lastname = user.object.lastname || 'untitiled' user.organization_id = organization_id Indexeddb.send(user); // Create default key let key = { method: 'object.create', storage: 'indexeddb', database: organization_id, array: 'keys', object: { _id: Crud.ObjectId().toString(), type: "key", key: apikey, actions: { signIn: true, signUp: true }, default: true }, organization_id } Indexeddb.send(key); // Create role let role_id = Crud.ObjectId().toString(); let role = { method: 'object.create', storage: 'indexeddb', database: organization_id, array: 'keys', object: { _id: role_id, type: "role", name: "admin", admin: "true" }, organization_id }; Indexeddb.send(role); // Create user key let userKey = { method: 'object.create', storage: 'indexeddb', database: organization_id, array: 'keys', object: { _id: Crud.ObjectId().toString(), type: "user", key: user_id, array: 'users', // could be any array roles: [role_id], email: user.object.email, password: user.object.password || btoa('0000') }, organization_id }; Indexeddb.send(userKey); return { organization: organization.object, apikey, user: user.object, role: role.object, userKey: userKey.object } } catch (error) { return false } } async function get() { let organization_id = await getOrganizationFromServiceWorker() if (!organization_id) { let data = await Indexeddb.send({ method: 'database.read' }) for (let database of data.database) { let name = database.name if (name.match(/^[0-9a-fA-F]{24}$/)) { organization_id = name } } } if (!organization_id) { let file = await fetch('/') organization_id = file.headers.get('organization'); } if (!organization_id) organization_id = await createOrganization() if (organization_id) Config.set('organization_id', organization_id) return organization_id } async function getOrganizationFromServiceWorker() { return new Promise((resolve, reject) => { if (!navigator.serviceWorker) return resolve() const handleMessage = (event) => { if (event.data.action === 'getOrganization') { navigator.serviceWorker.removeEventListener('message', handleMessage); // Remove the event listener resolve(event.data.organization_id); } }; navigator.serviceWorker.addEventListener('message', handleMessage); // Send message to Service Worker const msg = new MessageChannel(); navigator.serviceWorker.ready.then(registration => { if (navigator.serviceWorker.controller) { // If there's an active controller, send the message navigator.serviceWorker.controller.postMessage({ action: 'getOrganization' }, [msg.port1]); } else { // Listen for a new service worker to start controlling the page navigator.serviceWorker.addEventListener('controllerchange', () => { if (navigator.serviceWorker.controller) { navigator.serviceWorker.controller.postMessage({ action: 'getOrganization' }, [msg.port1]); } }); } }).catch(error => { console.error(reject); }); }); } let organizationPromise = null; async function createOrganizationPromise() { let createOrganization = document.querySelector('[actions*="createOrganization"]') if (createOrganization) return Crud.socket.organization = 'canceled' if (Crud.socket.organization == 'canceled' || Crud.socket.organization == 'pending') return const organization_id = prompt("An organization_id could not be found, if you already have an organization_id input it now.\n\nOr leave blank and click 'OK' to create a new organization"); if (organization_id) return organization_id if (organization_id === null) return Crud.socket.organization = 'canceled' Crud.socket.organization = 'pending' if (Indexeddb) { try { let org = { object: {} } if (organization_id) org.object._id = organization_id let { organization, apikey, user } = await generateDB(org) if (organization && apikey && user) { Crud.socket.apikey = apikey Crud.socket.user_id = user._id Config.set('organization_id', organization._id) Config.set('apikey', apikey) Config.set('user_id', user._id) Crud.socket.organization = true return organization._id } } catch (error) { console.error('Failed to load the script:', error); } } } async function createOrganization() { return organizationPromise || (organizationPromise = createOrganizationPromise()); } async function create(form) { if (!form) return; let organization = Elements.getData(form, 'organizations') let user = Elements.getData(form, 'users') if (!organization || !organization.object) return if (!user || !user.object) return if (!organization.object._id && !user.object._id) { let objects = await generateDB(organization, user) if (!objects) return } Elements.setTypeValue(form, organization) Elements.setTypeValue(form, user) organization = organization.object[0] user = user.object[0] let organization_id = organization._id if (Crud.socket.organization !== true) { Crud.socket.organization = true Crud.socket.create({ organization_id }) } let response = await Crud.socket.send({ method: 'createOrganization', organization, user, broadcastBrowser: false, organization_id }); document.dispatchEvent(new CustomEvent('createdOrganization', { detail: response })); } Action.init({ name: "createOrganization", endEvent: "createdOrganization", callback: (action) => { create(action.form); } }); export default { generateDB, create, get };