Fixing issues
This commit is contained in:
@@ -1,5 +1,6 @@
|
|||||||
import express, { Request, Response } from "express"
|
import express, { Request, Response } from "express"
|
||||||
import { join } from "path"
|
import { join } from "path"
|
||||||
|
import { isArray } from "lodash"
|
||||||
|
|
||||||
import { NODE_ENV } from "@/config"
|
import { NODE_ENV } from "@/config"
|
||||||
import dbMigrationClient from "@/db/db-migration-client"
|
import dbMigrationClient from "@/db/db-migration-client"
|
||||||
@@ -35,7 +36,10 @@ export class Migrator {
|
|||||||
|
|
||||||
this.migrationRouter.get("/seed/:environment", async (req: Request, res: Response) => {
|
this.migrationRouter.get("/seed/:environment", async (req: Request, res: Response) => {
|
||||||
try {
|
try {
|
||||||
await this.seedUp(req.params.environment)
|
const environment = isArray(req.params.environment)
|
||||||
|
? req.params.environment[0]
|
||||||
|
: req.params.environment
|
||||||
|
await this.seedUp(environment)
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
logger.error(err)
|
logger.error(err)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -38,7 +38,7 @@ export async function authorizationMiddleware(
|
|||||||
|
|
||||||
try {
|
try {
|
||||||
const token = req.headers.authorization || ""
|
const token = req.headers.authorization || ""
|
||||||
const user = await Users.EnsureFromAuth0TokenService.perform(token)
|
const user = await Users.FindFromAuth0TokenService.perform(token)
|
||||||
req.currentUser = user
|
req.currentUser = user
|
||||||
return next()
|
return next()
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
|
|||||||
@@ -0,0 +1,35 @@
|
|||||||
|
import { auth0Integration } from "@/integrations"
|
||||||
|
import { User } from "@/models"
|
||||||
|
import { Op } from "@sequelize/core"
|
||||||
|
import BaseService from "@/services/base-service"
|
||||||
|
|
||||||
|
export class FindFromAuth0TokenService extends BaseService {
|
||||||
|
constructor(private token: string) {
|
||||||
|
super()
|
||||||
|
}
|
||||||
|
|
||||||
|
async perform(): Promise<User> {
|
||||||
|
const { auth0Subject, email } = await auth0Integration.getUserInfo(this.token)
|
||||||
|
|
||||||
|
const existingUser = await User.withScope(["asCurrentUser"]).findOne({
|
||||||
|
where: { auth0Subject },
|
||||||
|
})
|
||||||
|
|
||||||
|
if (existingUser) {
|
||||||
|
return existingUser
|
||||||
|
}
|
||||||
|
|
||||||
|
const firstTimeUser = await User.withScope(["asCurrentUser"]).findOne({
|
||||||
|
where: { [Op.or]: [{ auth0Subject: email }, { email: email }] },
|
||||||
|
})
|
||||||
|
|
||||||
|
if (firstTimeUser) {
|
||||||
|
await firstTimeUser.update({ auth0Subject })
|
||||||
|
return firstTimeUser
|
||||||
|
}
|
||||||
|
|
||||||
|
throw new Error("No user found for this token.")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
export default FindFromAuth0TokenService
|
||||||
@@ -4,3 +4,4 @@ export { DestroyService } from "./destroy-service"
|
|||||||
|
|
||||||
// Special Services
|
// Special Services
|
||||||
export { EnsureFromAuth0TokenService } from "./ensure-from-auth0-token-service"
|
export { EnsureFromAuth0TokenService } from "./ensure-from-auth0-token-service"
|
||||||
|
export { FindFromAuth0TokenService } from "./find-from-auth0-token-service"
|
||||||
|
|||||||
@@ -0,0 +1,85 @@
|
|||||||
|
import http from "@/api/http-client"
|
||||||
|
import { type Policy } from "@/api/base-api"
|
||||||
|
|
||||||
|
// Keep in sync with api/src/models/notification.ts
|
||||||
|
export enum NotificationSourceTypes {
|
||||||
|
SYSTEM = "system",
|
||||||
|
}
|
||||||
|
|
||||||
|
export type Notification = {
|
||||||
|
id: number
|
||||||
|
userId: number
|
||||||
|
isRead: boolean
|
||||||
|
readDate: string | null
|
||||||
|
title: string
|
||||||
|
subtitle: string | null
|
||||||
|
href: string | null
|
||||||
|
sourceType: NotificationSourceTypes
|
||||||
|
createdAt: string
|
||||||
|
updatedAt: string
|
||||||
|
}
|
||||||
|
|
||||||
|
export type NotificationWhereOptions = {
|
||||||
|
userId?: number
|
||||||
|
isRead?: boolean
|
||||||
|
sourceType?: NotificationSourceTypes
|
||||||
|
}
|
||||||
|
|
||||||
|
export type NotificationFiltersOptions = {
|
||||||
|
createdTodayInUserTimezone?: string
|
||||||
|
}
|
||||||
|
|
||||||
|
export const notificationsApi = {
|
||||||
|
async list(
|
||||||
|
params: {
|
||||||
|
where?: NotificationWhereOptions
|
||||||
|
filters?: NotificationFiltersOptions
|
||||||
|
page?: number
|
||||||
|
perPage?: number
|
||||||
|
} = {}
|
||||||
|
): Promise<{
|
||||||
|
notifications: Notification[]
|
||||||
|
totalCount: number
|
||||||
|
}> {
|
||||||
|
const { data } = await http.get("/api/notifications", {
|
||||||
|
params,
|
||||||
|
})
|
||||||
|
return data
|
||||||
|
},
|
||||||
|
async get(notificationId: number): Promise<{
|
||||||
|
notification: Notification
|
||||||
|
policy: Policy
|
||||||
|
}> {
|
||||||
|
const { data } = await http.get(`/api/notifications/${notificationId}`)
|
||||||
|
return data
|
||||||
|
},
|
||||||
|
async create(attributes: Partial<Notification>): Promise<{
|
||||||
|
notification: Notification
|
||||||
|
}> {
|
||||||
|
const { data } = await http.post("/api/notifications", attributes)
|
||||||
|
return data
|
||||||
|
},
|
||||||
|
async update(
|
||||||
|
notificationId: number,
|
||||||
|
attributes: Partial<Notification>
|
||||||
|
): Promise<{
|
||||||
|
notification: Notification
|
||||||
|
}> {
|
||||||
|
const { data } = await http.patch(`/api/notifications/${notificationId}`, attributes)
|
||||||
|
return data
|
||||||
|
},
|
||||||
|
async delete(notificationId: number): Promise<void> {
|
||||||
|
const { data } = await http.delete(`/api/notifications/${notificationId}`)
|
||||||
|
return data
|
||||||
|
},
|
||||||
|
|
||||||
|
// Special actions
|
||||||
|
async markAll({ isRead }: { isRead: boolean }): Promise<void> {
|
||||||
|
const { data } = await http.post("/api/notifications/mark-all", {
|
||||||
|
isRead,
|
||||||
|
})
|
||||||
|
return data
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
export default notificationsApi
|
||||||
@@ -46,7 +46,7 @@
|
|||||||
import { computed } from "vue"
|
import { computed } from "vue"
|
||||||
import { useDisplay } from "vuetify"
|
import { useDisplay } from "vuetify"
|
||||||
|
|
||||||
import HeaderActionsCard from "@/components/shared/cards/HeaderActionsCard.vue"
|
import HeaderActionsCard from "@/components/common/HeaderActionsCard.vue"
|
||||||
|
|
||||||
const props = withDefaults(
|
const props = withDefaults(
|
||||||
defineProps<{
|
defineProps<{
|
||||||
|
|||||||
@@ -48,7 +48,7 @@
|
|||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script lang="ts" setup>
|
<script lang="ts" setup>
|
||||||
import SplashImage from "@/assets/SplashImage.png"
|
import SplashImage from "@/assets/app_logo_splash.png"
|
||||||
import { useAuth0 } from "@auth0/auth0-vue"
|
import { useAuth0 } from "@auth0/auth0-vue"
|
||||||
|
|
||||||
import { APPLICATION_NAME } from "@/config"
|
import { APPLICATION_NAME } from "@/config"
|
||||||
|
|||||||
@@ -48,7 +48,7 @@
|
|||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script lang="ts" setup>
|
<script lang="ts" setup>
|
||||||
import SplashImage from "@/assets/SplashImage.png"
|
import SplashImage from "@/assets/app_logo_splash.png"
|
||||||
import { useAuth0 } from "@auth0/auth0-vue"
|
import { useAuth0 } from "@auth0/auth0-vue"
|
||||||
|
|
||||||
import { APPLICATION_NAME } from "@/config"
|
import { APPLICATION_NAME } from "@/config"
|
||||||
|
|||||||
@@ -48,7 +48,7 @@
|
|||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script lang="ts" setup>
|
<script lang="ts" setup>
|
||||||
import SplashImage from "@/assets/SplashImage.png"
|
import SplashImage from "@/assets/app_logo_splash.png"
|
||||||
import { useAuth0 } from "@auth0/auth0-vue"
|
import { useAuth0 } from "@auth0/auth0-vue"
|
||||||
|
|
||||||
import { APPLICATION_NAME } from "@/config"
|
import { APPLICATION_NAME } from "@/config"
|
||||||
|
|||||||
@@ -48,7 +48,7 @@
|
|||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script lang="ts" setup>
|
<script lang="ts" setup>
|
||||||
import SplashImage from "@/assets/SplashImage.png"
|
import SplashImage from "@/assets/app_logo_splash.png"
|
||||||
import { useAuth0 } from "@auth0/auth0-vue"
|
import { useAuth0 } from "@auth0/auth0-vue"
|
||||||
|
|
||||||
import { APPLICATION_NAME } from "@/config"
|
import { APPLICATION_NAME } from "@/config"
|
||||||
|
|||||||
@@ -6,7 +6,6 @@
|
|||||||
|
|
||||||
// Styles
|
// Styles
|
||||||
import "@mdi/font/css/materialdesignicons.css"
|
import "@mdi/font/css/materialdesignicons.css"
|
||||||
import "vuetify/styles"
|
|
||||||
|
|
||||||
// ComposablesF
|
// ComposablesF
|
||||||
import { createVuetify } from "vuetify"
|
import { createVuetify } from "vuetify"
|
||||||
|
|||||||
@@ -66,31 +66,6 @@ export function useUser(id: Ref<number | null | undefined>) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
async function directorySync() {
|
|
||||||
const staticId = unref(id)
|
|
||||||
if (isNil(staticId)) {
|
|
||||||
throw new Error("id is required")
|
|
||||||
}
|
|
||||||
|
|
||||||
if (isNil(state.user)) {
|
|
||||||
throw new Error("No user to save")
|
|
||||||
}
|
|
||||||
|
|
||||||
state.isLoading = true
|
|
||||||
try {
|
|
||||||
const { user } = await usersApi.directorySync(staticId)
|
|
||||||
state.isErrored = false
|
|
||||||
state.user = user
|
|
||||||
return user
|
|
||||||
} catch (error) {
|
|
||||||
console.error("Failed to sync user:", error)
|
|
||||||
state.isErrored = true
|
|
||||||
throw error
|
|
||||||
} finally {
|
|
||||||
state.isLoading = false
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
watch(
|
watch(
|
||||||
() => unref(id),
|
() => unref(id),
|
||||||
async (newId) => {
|
async (newId) => {
|
||||||
@@ -106,7 +81,6 @@ export function useUser(id: Ref<number | null | undefined>) {
|
|||||||
fetch,
|
fetch,
|
||||||
refresh: fetch,
|
refresh: fetch,
|
||||||
save,
|
save,
|
||||||
directorySync,
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user