-
Notifications
You must be signed in to change notification settings - Fork 47
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Placename search settings for web and mobile
- Loading branch information
Showing
39 changed files
with
1,088 additions
and
127 deletions.
There are no files selected for viewing
83 changes: 83 additions & 0 deletions
83
service/src/adapters/settings/adapters.settings.controllers.web.ts
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,83 @@ | ||
import express from 'express' | ||
import { WebAppRequestFactory } from '../adapters.controllers.web' | ||
import { GetSettingsServices, UpdateMapSettingsRequest, UpdateSettingsServices } from '../../app.api/settings/app.api.settings' | ||
import { MobileSearchType, WebSearchType } from '../../entities/settings/entities.settings' | ||
import { URL } from 'url' | ||
|
||
export interface SettingsAppLayer { | ||
getMapSettings: GetSettingsServices, | ||
updateMapSettings: UpdateSettingsServices | ||
} | ||
|
||
function validateUrl(url: string): boolean { | ||
try { | ||
new URL(url) | ||
return true | ||
} catch (e) { return false } | ||
} | ||
|
||
export function SettingsRoutes(app: SettingsAppLayer, createAppRequest: WebAppRequestFactory) { | ||
const routes = express.Router() | ||
routes.use(express.json()) | ||
|
||
routes.route('/map') | ||
.get(async (req, res) => { | ||
const appReq = createAppRequest(req) | ||
const appRes = await app.getMapSettings(appReq) | ||
if (appRes.success) { | ||
return res.json(appRes.success) | ||
} else { | ||
return res.sendStatus(404) | ||
} | ||
}) | ||
|
||
routes.route('/map') | ||
.post(async (req, res) => { | ||
const { | ||
webSearchType: webSearchTypeParameter, | ||
mobileSearchType: mobileSearchTypeParameter, | ||
webNominatimUrl, | ||
mobileNominatimUrl | ||
} = req.body | ||
|
||
const webSearchType = WebSearchType[webSearchTypeParameter as keyof typeof WebSearchType] | ||
if (!webSearchType) { | ||
return res.status(400).json({ message: 'Web search option is required.' }) | ||
} | ||
|
||
const mobileSearchType = MobileSearchType[mobileSearchTypeParameter as keyof typeof MobileSearchType] | ||
if (!mobileSearchType) { | ||
return res.status(400).json({ message: 'Mobile search option is required.' }) | ||
} | ||
|
||
if (webSearchType === WebSearchType.NOMINATIM) { | ||
if (!validateUrl(webNominatimUrl)) { | ||
return res.status(400).json({ message: 'Web Nominatim URL is required and must be a valid URL.' }) | ||
} | ||
} | ||
|
||
if (mobileSearchType === MobileSearchType.NOMINATIM) { | ||
if (!validateUrl(mobileNominatimUrl)) { | ||
return res.status(400).json({ message: 'Mobile Nominatim URL is required and must be a vaild URL.' }) | ||
} | ||
} | ||
|
||
const settings: UpdateMapSettingsRequest['settings'] = { | ||
webSearchType: webSearchType, | ||
webNominatimUrl: req.body.webNominatimUrl, | ||
mobileSearchType: mobileSearchType, | ||
mobileNominatimUrl: req.body.mobileNominatimUrl | ||
} | ||
|
||
const appReq: UpdateMapSettingsRequest = createAppRequest(req, { settings }) | ||
|
||
const appRes = await app.updateMapSettings(appReq) | ||
if (appRes.success) { | ||
return res.json(appRes.success) | ||
} else { | ||
return res.sendStatus(400) | ||
} | ||
}) | ||
|
||
return routes | ||
} |
33 changes: 33 additions & 0 deletions
33
service/src/adapters/settings/adapters.settings.db.mongoose.ts
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,33 @@ | ||
import { BaseMongooseRepository } from '../base/adapters.base.db.mongoose' | ||
import * as legacy from '../../models/setting' | ||
import _ from 'lodash' | ||
import mongoose from 'mongoose' | ||
import { MapSettings, SettingRepository } from '../../entities/settings/entities.settings' | ||
|
||
export type SettingsDocument = legacy.SettingsDocument | ||
export type SettingsModel = mongoose.Model<SettingsDocument> | ||
export const SettingsSchema = legacy.Model.schema | ||
|
||
export class MongooseSettingsRepository extends BaseMongooseRepository<SettingsDocument, SettingsModel, MapSettings> implements SettingRepository { | ||
|
||
constructor(model: mongoose.Model<SettingsDocument>) { | ||
super(model, { | ||
docToEntity: doc => { | ||
const json = doc.toJSON() | ||
return { | ||
...json | ||
} | ||
} | ||
}) | ||
} | ||
|
||
async getMapSettings(): Promise<MapSettings | null> { | ||
const document = await this.model.findOne({ type: 'map' }) | ||
return document?.settings | ||
} | ||
|
||
async updateMapSettings(settings: MapSettings): Promise<MapSettings | null> { | ||
const document = await this.model.findOneAndUpdate({ type: 'map' }, { settings }, { new: true, upsert: true }) | ||
return document?.settings | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,20 @@ | ||
import { MapSettings } from '../../entities/settings/entities.settings' | ||
import { PermissionDeniedError } from '../app.api.errors' | ||
import { AppRequest, AppRequestContext, AppResponse } from '../app.api.global' | ||
|
||
export interface UpdateMapSettingsRequest extends AppRequest { | ||
settings: MapSettings | ||
} | ||
|
||
export interface GetSettingsServices { | ||
(req: AppRequest): Promise<AppResponse<MapSettings | null, PermissionDeniedError>> | ||
} | ||
|
||
export interface UpdateSettingsServices { | ||
(req: UpdateMapSettingsRequest): Promise<AppResponse<MapSettings | null, PermissionDeniedError>> | ||
} | ||
|
||
export interface SettingsPermissionService { | ||
ensureFetchMapSettingsPermissionFor(context: AppRequestContext): Promise<PermissionDeniedError | null> | ||
ensureUpdateMapSettingsPermissionFor(context: AppRequestContext): Promise<PermissionDeniedError | null> | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,26 @@ | ||
import * as api from '../../app.api/settings/app.api.settings' | ||
import { AppRequest, KnownErrorsOf, withPermission } from '../../app.api/app.api.global' | ||
import { MapSettings, SettingRepository } from '../../entities/settings/entities.settings' | ||
import { UpdateMapSettingsRequest } from '../../app.api/settings/app.api.settings' | ||
|
||
export function FetchMapSettings(settingRepo: SettingRepository, permissionService: api.SettingsPermissionService): api.GetSettingsServices { | ||
return async function getMapSettings(req: AppRequest): ReturnType<api.GetSettingsServices> { | ||
return await withPermission<MapSettings | null, KnownErrorsOf<api.GetSettingsServices>>( | ||
permissionService.ensureFetchMapSettingsPermissionFor(req.context), | ||
async (): Promise<MapSettings | null> => { | ||
return await settingRepo.getMapSettings() | ||
} | ||
) | ||
} | ||
} | ||
|
||
export function UpdateMapSettings(settingRepo: SettingRepository, permissionService: api.SettingsPermissionService): api.UpdateSettingsServices { | ||
return async function updateMapSettings(req: UpdateMapSettingsRequest): ReturnType<api.UpdateSettingsServices> { | ||
return await withPermission<MapSettings | null, KnownErrorsOf<api.UpdateSettingsServices>>( | ||
permissionService.ensureUpdateMapSettingsPermissionFor(req.context), | ||
async (): Promise<MapSettings | null> => { | ||
return await settingRepo.updateMapSettings(req.settings) | ||
} | ||
) | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,22 @@ | ||
export enum WebSearchType { | ||
NONE = "NONE", | ||
NOMINATIM = "NOMINATIM" | ||
} | ||
|
||
export enum MobileSearchType { | ||
NONE = "NONE", | ||
NATIVE = "NATIVE", | ||
NOMINATIM = "NOMINATIM" | ||
} | ||
|
||
export interface MapSettings { | ||
webSearchType: WebSearchType | ||
webNominatimUrl: string | null | ||
mobileSearchType: MobileSearchType | ||
mobileNominatimUrl: string | null | ||
} | ||
|
||
export interface SettingRepository { | ||
getMapSettings(): Promise<MapSettings | null> | ||
updateMapSettings(settings: MapSettings): Promise<MapSettings | null> | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,40 @@ | ||
exports.id = 'map-search-settings'; | ||
|
||
exports.up = async function (done) { | ||
|
||
const roles = this.db.collection('roles'); | ||
try { | ||
await roles.update({name: 'USER_ROLE'}, { $push: { permissions: 'MAP_SETTINGS_READ' } }); | ||
} catch (e) { done(e) } | ||
|
||
try { | ||
await roles.update({ name: 'USER_NO_EDIT_ROLE' }, { $push: { permissions: 'MAP_SETTINGS_READ' } }); | ||
} catch (e) { done(e) } | ||
|
||
|
||
try { | ||
await roles.update({ name: 'EVENT_MANAGER_ROLE' }, { $push: { permissions: 'MAP_SETTINGS_READ' } }); | ||
} catch (e) { done(e) } | ||
|
||
try { | ||
await roles.update({ name: 'ADMIN_ROLE' }, { $push: { permissions: { $each: ['MAP_SETTINGS_READ', 'MAP_SETTINGS_UPDATE'] } } }); | ||
} catch (e) { done(e) } | ||
|
||
const settings = this.db.collection('settings'); | ||
try { | ||
await settings.insertOne({ | ||
type: 'map', | ||
settings: { | ||
webSearchType: "NOMINATIM", | ||
webNominatimUrl: "https://nominatim.openstreetmap.org", | ||
mobileSearchType: "NATIVE", | ||
} | ||
}); | ||
} catch (e) { done(e) } | ||
|
||
done(); | ||
}; | ||
|
||
exports.down = function (done) { | ||
done(); | ||
}; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,9 @@ | ||
import mongoose from 'mongoose' | ||
|
||
export interface SettingsDocument extends mongoose.Document { | ||
_id: mongoose.Types.ObjectId | ||
type: string | ||
settings: any | ||
} | ||
|
||
export declare const Model: mongoose.Model<SettingsDocument> |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.