1
0
Fork 0
mirror of synced 2024-05-02 11:32:26 +12:00
budibase/packages/builder/src/stores/portal/auth.js
2022-11-11 11:26:36 +00:00

202 lines
5 KiB
JavaScript

import { derived, writable, get } from "svelte/store"
import { API } from "api"
import { admin } from "stores/portal"
import analytics from "analytics"
export function createAuthStore() {
const auth = writable({
user: null,
accountPortalAccess: false,
tenantId: "default",
tenantSet: false,
loaded: false,
postLogout: false,
})
const store = derived(auth, $store => {
let initials = null
let isAdmin = false
let isBuilder = false
if ($store.user) {
const user = $store.user
if (user.firstName) {
initials = user.firstName[0]
if (user.lastName) {
initials += user.lastName[0]
}
} else if (user.email) {
initials = user.email[0]
} else {
initials = "Unknown"
}
isAdmin = !!user.admin?.global
isBuilder = !!user.builder?.global
}
return {
user: $store.user,
accountPortalAccess: $store.accountPortalAccess,
tenantId: $store.tenantId,
tenantSet: $store.tenantSet,
loaded: $store.loaded,
postLogout: $store.postLogout,
initials,
isAdmin,
isBuilder,
}
})
function setUser(user) {
auth.update(store => {
store.loaded = true
store.user = user
store.accountPortalAccess = user?.accountPortalAccess
if (user) {
store.tenantId = user.tenantId || "default"
store.tenantSet = true
}
return store
})
if (user) {
analytics
.activate()
.then(() => {
analytics.identify(user._id)
analytics.showChat(
{
email: user.email,
created_at: (user.createdAt || Date.now()) / 1000,
name: user.account?.name,
user_id: user._id,
tenant: user.tenantId,
admin: user?.admin?.global,
builder: user?.builder?.global,
"Company size": user.account?.size,
"Job role": user.account?.profession,
},
!!user?.account
)
})
.catch(() => {
// This request may fail due to browser extensions blocking requests
// containing the word analytics, so we don't want to spam users with
// an error here.
})
}
}
async function setOrganisation(tenantId) {
const prevId = get(store).tenantId
auth.update(store => {
store.tenantId = tenantId
store.tenantSet = !!tenantId
return store
})
if (prevId !== tenantId) {
// re-init admin after setting org
await admin.init()
}
}
async function setInitInfo(info) {
await API.setInitInfo(info)
auth.update(store => {
store.initInfo = info
return store
})
return info
}
function setPostLogout() {
auth.update(store => {
store.postLogout = true
return store
})
}
async function getInitInfo() {
const info = await API.getInitInfo()
auth.update(store => {
store.initInfo = info
return store
})
return info
}
const actions = {
checkQueryString: async () => {
const urlParams = new URLSearchParams(window.location.search)
if (urlParams.has("tenantId")) {
const tenantId = urlParams.get("tenantId")
await setOrganisation(tenantId)
}
},
setOrg: async tenantId => {
await setOrganisation(tenantId)
},
getSelf: async () => {
// We need to catch this locally as we never want this to fail, even
// though normally we never want to swallow API errors at the store level.
// We're either logged in or we aren't.
// We also need to always update the loaded flag.
try {
const user = await API.fetchBuilderSelf()
setUser(user)
} catch (error) {
setUser(null)
}
},
login: async creds => {
const tenantId = get(store).tenantId
await API.logIn({
username: creds.username,
password: creds.password,
tenantId,
})
await actions.getSelf()
},
logout: async () => {
await API.logOut()
setPostLogout()
setUser(null)
await setInitInfo({})
},
updateSelf: async fields => {
const newUser = { ...get(auth).user, ...fields }
await API.updateSelf(newUser)
setUser(newUser)
},
forgotPassword: async email => {
const tenantId = get(store).tenantId
await API.requestForgotPassword({
tenantId,
email,
})
},
resetPassword: async (password, resetCode) => {
const tenantId = get(store).tenantId
await API.resetPassword({
tenantId,
password,
resetCode,
})
},
generateAPIKey: async () => {
return API.generateAPIKey()
},
fetchAPIKey: async () => {
const info = await API.fetchDeveloperInfo()
return info?.apiKey
},
}
return {
subscribe: store.subscribe,
setOrganisation,
getInitInfo,
setInitInfo,
...actions,
}
}
export const auth = createAuthStore()