Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
32 changes: 31 additions & 1 deletion app/locals.js
Original file line number Diff line number Diff line change
@@ -1,5 +1,18 @@
module.exports = function(req, res, next) {

const buildSwitchedPharmacyOrganisationSetting = (sessionData, currentOrganisationId) => {
if (!sessionData.previousOrganisationId || !currentOrganisationId) {
return null
}

return {
id: currentOrganisationId,
status: 'Active',
permissionLevel: 'Lead administrator',
vaccinator: false
}
}

const monthNames = [
'January',
'February',
Expand All @@ -25,7 +38,24 @@ module.exports = function(req, res, next) {

// Set currentUser for convenience
if (req.session.data.currentUserId) {
res.locals.currentUser = req.session.data.users.find((user) => user.id === req.session.data.currentUserId)
const sessionUser = req.session.data.users.find((user) => user.id === req.session.data.currentUserId)
const switchedOrganisationSetting = buildSwitchedPharmacyOrganisationSetting(
req.session.data,
req.session.data.currentOrganisationId
)

if (sessionUser && switchedOrganisationSetting) {
const userOrganisations = (sessionUser.organisations || [])
.filter((organisation) => organisation.id !== switchedOrganisationSetting.id)
.map((organisation) => ({ ...organisation }))

res.locals.currentUser = {
...sessionUser,
organisations: [...userOrganisations, switchedOrganisationSetting]
}
} else {
res.locals.currentUser = sessionUser
}
} else {
res.locals.currentUser = null
}
Expand Down
207 changes: 207 additions & 0 deletions app/routes/auth.js
Original file line number Diff line number Diff line change
@@ -1,5 +1,13 @@
module.exports = router => {

const asArray = (value) => {
if (value === undefined || value === null) {
return []
}

return Array.isArray(value) ? value : [value]
}

const getDefaultLandingPath = (data, organisationId) => {
const organisation = (data.organisations || []).find((item) => item.id === organisationId)

Expand All @@ -22,6 +30,114 @@ module.exports = router => {
return '/home'
}

const getCurrentUserFromSessionData = (data) => {
if (!data) {
return null
}

if (data.currentUserId) {
return (data.users || []).find((user) => user.id === data.currentUserId) || null
}

if (data.email) {
return (data.users || []).find((user) => user.email === data.email) || null
}

return null
}

router.get('/auth/restore-organisation', (req, res) => {
const data = req.session.data
const previousOrganisationId = data.previousOrganisationId
const previousOrganisation = (data.organisations || []).find((organisation) => organisation.id === previousOrganisationId)

if (!previousOrganisationId) {
return res.redirect('/auth/select-organisation')
}

data.currentOrganisationId = previousOrganisationId
delete data.previousOrganisationId

if (previousOrganisation && previousOrganisation.type === 'Pharmacy HQ') {
return res.redirect('/pharmacies')
}

res.redirect(getDefaultLandingPath(data, previousOrganisationId))
})

const isTemporaryAccessInactive = (addedOnIsoDate, deactivatedOnIsoDate) => {
if (deactivatedOnIsoDate) {
return true
}

if (!addedOnIsoDate) {
return false
}

const expiryDate = new Date(`${addedOnIsoDate}T12:00:00`)
expiryDate.setDate(expiryDate.getDate() + 7)

const today = new Date()
today.setHours(0, 0, 0, 0)

return expiryDate < today
}

const getGroupAdminSwitchContext = (data, user) => {
if (!data || !user) {
return {
isEligible: false,
groupOrganisation: null,
temporaryPharmacies: []
}
}

const activeGroupAdminOrganisationIds = (user.organisations || [])
.filter((organisation) => organisation.permissionLevel === 'Group administrator' && organisation.status === 'Active')
.map((organisation) => organisation.id)

const groupOrganisation = (data.organisations || []).find((organisation) => {
return organisation.type === 'Pharmacy HQ' && activeGroupAdminOrganisationIds.includes(organisation.id)
})

if (!groupOrganisation) {
return {
isEligible: false,
groupOrganisation: null,
temporaryPharmacies: []
}
}

const temporaryPharmacyIds = [...new Set(asArray(data.groupAdminTemporaryPharmacyIds))]
const temporaryPharmacyAddedDates = data.groupAdminTemporaryPharmacyAddedDates || {}
const temporaryPharmacyDeactivatedDates = data.groupAdminTemporaryPharmacyDeactivatedDates || {}

const temporaryPharmacies = temporaryPharmacyIds
.map((pharmacyId) => {
const organisation = (data.organisations || []).find((item) => item.id === pharmacyId)

return {
organisation,
addedOn: temporaryPharmacyAddedDates[pharmacyId],
deactivatedOn: temporaryPharmacyDeactivatedDates[pharmacyId]
}
})
.filter((item) => item.organisation)
.filter((organisation) => {
return organisation.organisation.status === 'Active' && organisation.organisation.companyId === groupOrganisation.id
})
.filter((item) => {
return !isTemporaryAccessInactive(item.addedOn, item.deactivatedOn)
})
.map((item) => item.organisation)

return {
isEligible: temporaryPharmacies.length > 1,
groupOrganisation,
temporaryPharmacies
}
}

router.post('/auth/sign-in', (req, res) => {

const data = req.session.data
Expand Down Expand Up @@ -119,6 +235,97 @@ module.exports = router => {
}
})

router.get('/auth/switch-organisation/work-type', (req, res) => {
const data = req.session.data
const user = getCurrentUserFromSessionData(data)
const context = getGroupAdminSwitchContext(data, user)

if (!user || !context.isEligible) {
return res.redirect('/auth/select-organisation')
}

res.render('auth/switch-work-type', {
groupOrganisation: context.groupOrganisation
})
})

router.post('/auth/switch-organisation/work-type', (req, res) => {
const data = req.session.data
const user = getCurrentUserFromSessionData(data)
const context = getGroupAdminSwitchContext(data, user)
const switchOrganisationWorkType = req.body.switchOrganisationWorkType

if (!user || !context.isEligible) {
return res.redirect('/auth/select-organisation')
}

if (!switchOrganisationWorkType) {
return res.render('auth/switch-work-type', {
groupOrganisation: context.groupOrganisation,
error: {
text: 'Select the type of work you want to do'
}
})
}

if (switchOrganisationWorkType === 'group-admin') {
data.currentOrganisationId = context.groupOrganisation.id
return res.redirect(getDefaultLandingPath(data, context.groupOrganisation.id))
}

if (switchOrganisationWorkType === 'individual-pharmacy') {
return res.redirect('/auth/switch-organisation/select-pharmacy')
}

res.render('auth/switch-work-type', {
groupOrganisation: context.groupOrganisation,
error: {
text: 'Select the type of work you want to do'
}
})
})

router.get('/auth/switch-organisation/select-pharmacy', (req, res) => {
const data = req.session.data
const user = getCurrentUserFromSessionData(data)
const context = getGroupAdminSwitchContext(data, user)

if (!user || !context.isEligible) {
return res.redirect('/auth/select-organisation')
}

res.render('auth/select-pharmacy-for-access', {
groupOrganisation: context.groupOrganisation,
pharmacies: context.temporaryPharmacies
})
})

router.post('/auth/switch-organisation/select-pharmacy', (req, res) => {
const data = req.session.data
const user = getCurrentUserFromSessionData(data)
const context = getGroupAdminSwitchContext(data, user)
const switchOrganisationPharmacyId = req.body.switchOrganisationPharmacyId

if (!user || !context.isEligible) {
return res.redirect('/auth/select-organisation')
}

const isValidSelection = context.temporaryPharmacies.some((pharmacy) => pharmacy.id === switchOrganisationPharmacyId)

if (!switchOrganisationPharmacyId || !isValidSelection) {
return res.render('auth/select-pharmacy-for-access', {
groupOrganisation: context.groupOrganisation,
pharmacies: context.temporaryPharmacies,
error: {
text: 'Select a pharmacy to access'
}
})
}

data.currentOrganisationId = switchOrganisationPharmacyId
res.redirect(getDefaultLandingPath(data, switchOrganisationPharmacyId))
})

router.get('/sign-out', (req, res) => {
req.session.data.currentUserId = null
req.session.data.currentOrganisationId = null
Expand Down
Loading