mirror of
https://github.com/jorgev259/soc_site-astro.git
synced 2025-06-29 07:57:41 +00:00
Add sequelize index file
This commit is contained in:
parent
6f00481c25
commit
d20b00532d
12 changed files with 77 additions and 50 deletions
|
|
@ -3,7 +3,14 @@ import { defineConfig } from 'auth-astro'
|
||||||
import Credentials from "@auth/core/providers/credentials"
|
import Credentials from "@auth/core/providers/credentials"
|
||||||
import bcrypt from 'bcrypt'
|
import bcrypt from 'bcrypt'
|
||||||
|
|
||||||
import db from '@/sequelize'
|
import User from '@/sequelize/models/user'
|
||||||
|
|
||||||
|
declare module "@auth/core" {
|
||||||
|
interface Session {
|
||||||
|
id: string
|
||||||
|
username: string
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
class InvalidLoginError extends CredentialsSignin {
|
class InvalidLoginError extends CredentialsSignin {
|
||||||
code = "Invalid username/email or password"
|
code = "Invalid username/email or password"
|
||||||
|
|
@ -19,7 +26,7 @@ export default defineConfig({
|
||||||
async authorize(credentials) {
|
async authorize(credentials) {
|
||||||
if (!credentials?.username || !credentials.password) throw new InvalidLoginError()
|
if (!credentials?.username || !credentials.password) throw new InvalidLoginError()
|
||||||
|
|
||||||
const user = await db.models.user.findByPk(credentials.username)
|
const user = await User.findByPk(credentials.username)
|
||||||
if (!user) throw new InvalidLoginError()
|
if (!user) throw new InvalidLoginError()
|
||||||
|
|
||||||
// @ts-ignore
|
// @ts-ignore
|
||||||
|
|
|
||||||
1
src/app.d.ts
vendored
1
src/app.d.ts
vendored
|
|
@ -1,7 +1,6 @@
|
||||||
import type { ParaglideLocals } from "@inlang/paraglide-sveltekit"
|
import type { ParaglideLocals } from "@inlang/paraglide-sveltekit"
|
||||||
import type { AvailableLanguageTag } from "$lib/paraglide/runtime"
|
import type { AvailableLanguageTag } from "$lib/paraglide/runtime"
|
||||||
|
|
||||||
|
|
||||||
declare global {
|
declare global {
|
||||||
namespace App {
|
namespace App {
|
||||||
interface Locals {
|
interface Locals {
|
||||||
|
|
|
||||||
|
|
@ -4,24 +4,21 @@ import { SchemaLink } from "@apollo/client/link/schema"
|
||||||
import { makeExecutableSchema } from "@graphql-tools/schema";
|
import { makeExecutableSchema } from "@graphql-tools/schema";
|
||||||
import { getSession } from 'auth-astro/server';
|
import { getSession } from 'auth-astro/server';
|
||||||
import type { Session } from '@auth/core/types';
|
import type { Session } from '@auth/core/types';
|
||||||
|
|
||||||
import { typeDefs } from "./__generated__/typeDefs.generated";
|
import { typeDefs } from "./__generated__/typeDefs.generated";
|
||||||
import resolvers from '@/graphql/resolvers'
|
import resolvers from '@/graphql/resolvers'
|
||||||
import type { MySqlDialect } from '@sequelize/mysql';
|
|
||||||
import { Sequelize, type ModelStatic, type Options } from '@sequelize/core'
|
import db from '@/sequelize';
|
||||||
|
|
||||||
const schema = makeExecutableSchema({ typeDefs, resolvers })
|
const schema = makeExecutableSchema({ typeDefs, resolvers })
|
||||||
export type ResolverContext = { request?: Request, session?: Session }
|
export type ResolverContext = { request?: Request, session?: Session }
|
||||||
|
|
||||||
const envOptions: Options<MySqlDialect> = JSON.parse(import.meta.env.SEQUELIZE) || {}
|
|
||||||
|
|
||||||
export async function getApolloClient(request?: Request) {
|
export async function getApolloClient(request?: Request) {
|
||||||
const session = request ? await getSession(request) : null
|
const session = request ? await getSession(request) : null
|
||||||
const db = new Sequelize(envOptions)
|
|
||||||
envOptions.models = Object.values<ModelStatic>(await import.meta.glob('@/sequelize/models/**/*.ts', { eager: true, import: 'default' }))
|
|
||||||
|
|
||||||
return new ApolloClient({
|
return new ApolloClient({
|
||||||
ssrMode: true,
|
ssrMode: true,
|
||||||
link: new SchemaLink({ schema, context: { request, session } }),
|
link: new SchemaLink({ schema, context: { request, session, db } }),
|
||||||
cache: new InMemoryCache()
|
cache: new InMemoryCache()
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
@ -1,5 +1,5 @@
|
||||||
import { composeResolvers } from '@graphql-tools/resolvers-composition'
|
import { composeResolvers } from '@graphql-tools/resolvers-composition'
|
||||||
import type { Resolvers } from '@/graphql/__generated__/types.generated'
|
// import type { Resolvers } from '@/graphql/__generated__/types.generated'
|
||||||
|
|
||||||
const resolversComposition = {
|
const resolversComposition = {
|
||||||
//'Mutation.updateUser': [isAuthedApp]
|
//'Mutation.updateUser': [isAuthedApp]
|
||||||
|
|
@ -49,7 +49,7 @@ async function cropPFP(streamItem, username, imgId) {
|
||||||
return await processImage(fullPath)
|
return await processImage(fullPath)
|
||||||
}*/
|
}*/
|
||||||
|
|
||||||
const resolvers: Resolvers = {
|
const resolvers = {
|
||||||
Mutation: {
|
Mutation: {
|
||||||
/*registerUser: async (_, { username, email, pfp }, { db }) => {
|
/*registerUser: async (_, { username, email, pfp }, { db }) => {
|
||||||
await Promise.all([
|
await Promise.all([
|
||||||
|
|
|
||||||
|
|
@ -8,6 +8,7 @@ const fuzzySearch = (words: string[]) => `^${words.map(w => `(?=.*\b${w}\b)`)}.+
|
||||||
|
|
||||||
const resolvers: Resolvers = {
|
const resolvers: Resolvers = {
|
||||||
Query: {
|
Query: {
|
||||||
|
// @ts-ignore
|
||||||
searchAlbum: async (_, args, { db }) => {
|
searchAlbum: async (_, args, { db }) => {
|
||||||
const { title, categories, limit = 10, offset = 0, order = ['createdAt'], mode = 'DESC', status = ['show'] } = args
|
const { title, categories, limit = 10, offset = 0, order = ['createdAt'], mode = 'DESC', status = ['show'] } = args
|
||||||
const fuzzyCondition = title ? {
|
const fuzzyCondition = title ? {
|
||||||
|
|
@ -27,6 +28,7 @@ const resolvers: Resolvers = {
|
||||||
status: { [Op.in]: status }
|
status: { [Op.in]: status }
|
||||||
},
|
},
|
||||||
include,
|
include,
|
||||||
|
// @ts-ignore
|
||||||
order: [literal('`album`.`status` = \'coming\' DESC'), ...order.map(o => [o, mode])]
|
order: [literal('`album`.`status` = \'coming\' DESC'), ...order.map(o => [o, mode])]
|
||||||
})
|
})
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -5,7 +5,8 @@ import type Album from "@/sequelize/models/album"
|
||||||
const resolvers: Resolvers = {
|
const resolvers: Resolvers = {
|
||||||
// Upload: GraphQLUpload,
|
// Upload: GraphQLUpload,
|
||||||
Album: {
|
Album: {
|
||||||
artists: (parent: Album, args, context, info) => parent.getArtists(),
|
// @ts-ignore
|
||||||
|
artists: (parent, args, context, info) => parent.getArtists(),
|
||||||
/* categories: (parent, args, context, info) => parent.getCategories(),
|
/* categories: (parent, args, context, info) => parent.getCategories(),
|
||||||
classifications: (parent, args, context, info) =>
|
classifications: (parent, args, context, info) =>
|
||||||
parent.getClassifications(),
|
parent.getClassifications(),
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,6 @@
|
||||||
import type { Resolvers } from '@/graphql/__generated__/types.generated'
|
// import type { Resolvers } from '@/graphql/__generated__/types.generated'
|
||||||
|
|
||||||
const userResolvable: Resolvers = {
|
const userResolvable = {
|
||||||
/* roles: parent => parent.getRoles(),
|
/* roles: parent => parent.getRoles(),
|
||||||
permissions: async parent => {
|
permissions: async parent => {
|
||||||
const roles = await parent.getRoles()
|
const roles = await parent.getRoles()
|
||||||
|
|
@ -8,26 +8,32 @@ const userResolvable: Resolvers = {
|
||||||
}, */
|
}, */
|
||||||
pages: async (_, __, { session }) => {
|
pages: async (_, __, { session }) => {
|
||||||
const roles = await parent.getRoles()
|
const roles = await parent.getRoles()
|
||||||
const permissions = roles.map(r => r.permissions).flat()
|
const permissions = roles.map((r) => r.permissions).flat()
|
||||||
|
|
||||||
return pages.filter(({ perms }) => perms.length === 0 || perms.some(r => permissions.includes(r)))
|
return pages.filter(
|
||||||
},
|
({ perms }) =>
|
||||||
|
perms.length === 0 || perms.some((r) => permissions.includes(r))
|
||||||
|
)
|
||||||
|
}
|
||||||
/* comments: (user, _, { db }) => user.getComments({ where: { albumId: { [Op.not]: null } } }),
|
/* comments: (user, _, { db }) => user.getComments({ where: { albumId: { [Op.not]: null } } }),
|
||||||
favorites: user => user.getAlbums(),
|
favorites: user => user.getAlbums(),
|
||||||
imgUrl: async user => `https://cdn.sittingonclouds.net/user/${user.imgId ? `${user.username}_${user.imgId}` : 'default'
|
imgUrl: async user => `https://cdn.sittingonclouds.net/user/${user.imgId ? `${user.username}_${user.imgId}` : 'default'
|
||||||
}.png` */
|
}.png` */
|
||||||
}
|
}
|
||||||
|
|
||||||
const resolvers: Resolvers = {
|
const resolvers = {
|
||||||
// User: userResolvable,
|
// User: userResolvable,
|
||||||
UserMe: {
|
UserMe: {
|
||||||
pages: async (_, __, { session }) => {
|
pages: async (_, __, { session }) => {
|
||||||
const roles = await parent.getRoles()
|
const roles = await parent.getRoles()
|
||||||
const permissions = roles.map(r => r.permissions).flat()
|
const permissions = roles.map((r) => r.permissions).flat()
|
||||||
|
|
||||||
return pages.filter(({ perms }) => perms.length === 0 || perms.some(r => permissions.includes(r)))
|
return pages.filter(
|
||||||
},
|
({ perms }) =>
|
||||||
},
|
perms.length === 0 || perms.some((r) => permissions.includes(r))
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
/*Role: { permissions: parent => typeof parent.permissions === 'string' || parent.permissions instanceof String ? JSON.parse(parent.permissions) : parent.permissions },
|
/*Role: { permissions: parent => typeof parent.permissions === 'string' || parent.permissions instanceof String ? JSON.parse(parent.permissions) : parent.permissions },
|
||||||
Submission: {
|
Submission: {
|
||||||
submitter: submission => submission.getUser(),
|
submitter: submission => submission.getUser(),
|
||||||
|
|
|
||||||
10
src/sequelize/index.ts
Normal file
10
src/sequelize/index.ts
Normal file
|
|
@ -0,0 +1,10 @@
|
||||||
|
import type { MySqlDialect } from '@sequelize/mysql';
|
||||||
|
import { Sequelize, type ModelStatic, type Options } from '@sequelize/core'
|
||||||
|
|
||||||
|
const envOptions: Options<MySqlDialect> = JSON.parse(import.meta.env.SEQUELIZE) || {}
|
||||||
|
const db = new Sequelize({
|
||||||
|
...envOptions,
|
||||||
|
models: Object.values<ModelStatic>(await import.meta.glob('@/sequelize/models/**/*.ts', { eager: true, import: 'default' }))
|
||||||
|
})
|
||||||
|
|
||||||
|
export default db
|
||||||
|
|
@ -1,10 +1,7 @@
|
||||||
import { DataTypes, Model, type CreationOptional, type InferAttributes, type InferCreationAttributes } from '@sequelize/core';
|
import { DataTypes, Model, type CreationOptional, type InferAttributes, type InferCreationAttributes } from '@sequelize/core';
|
||||||
import { Attribute, PrimaryKey, AutoIncrement, Default, Table } from '@sequelize/core/decorators-legacy';
|
import { Attribute, PrimaryKey, AutoIncrement, Default, Table } from '@sequelize/core/decorators-legacy';
|
||||||
|
|
||||||
@Table({
|
@Table({ tableName: 'config' })
|
||||||
freezeTableName: true,
|
|
||||||
})
|
|
||||||
|
|
||||||
export default class Config extends Model<InferAttributes<Config>, InferCreationAttributes<Config>> {
|
export default class Config extends Model<InferAttributes<Config>, InferCreationAttributes<Config>> {
|
||||||
@Attribute(DataTypes.ENUM('banner', 'banner-position'))
|
@Attribute(DataTypes.ENUM('banner', 'banner-position'))
|
||||||
@PrimaryKey
|
@PrimaryKey
|
||||||
|
|
|
||||||
|
|
@ -1,23 +0,0 @@
|
||||||
import { DataTypes } from '@/sequelize'
|
|
||||||
|
|
||||||
const model = (sequelize) => {
|
|
||||||
const User = sequelize.define('user', {
|
|
||||||
username: {
|
|
||||||
type: DataTypes.STRING,
|
|
||||||
primaryKey: true
|
|
||||||
},
|
|
||||||
email: DataTypes.STRING,
|
|
||||||
password: DataTypes.STRING,
|
|
||||||
placeholder: { type: DataTypes.TEXT },
|
|
||||||
imgId: DataTypes.STRING
|
|
||||||
})
|
|
||||||
|
|
||||||
sequelize.define('forgor', {
|
|
||||||
key: { type: DataTypes.STRING, primaryKey: true },
|
|
||||||
expires: DataTypes.DATE
|
|
||||||
})
|
|
||||||
|
|
||||||
return User
|
|
||||||
}
|
|
||||||
|
|
||||||
export default model
|
|
||||||
20
src/sequelize/models/user.ts
Normal file
20
src/sequelize/models/user.ts
Normal file
|
|
@ -0,0 +1,20 @@
|
||||||
|
import { DataTypes, Model, type InferAttributes, type InferCreationAttributes } from '@sequelize/core'
|
||||||
|
import { Attribute, NotNull, PrimaryKey } from '@sequelize/core/decorators-legacy'
|
||||||
|
|
||||||
|
export default class User extends Model<InferAttributes<User>, InferCreationAttributes<User>> {
|
||||||
|
@PrimaryKey
|
||||||
|
@Attribute(DataTypes.STRING)
|
||||||
|
declare username: string
|
||||||
|
|
||||||
|
@Attribute(DataTypes.STRING)
|
||||||
|
@NotNull
|
||||||
|
declare email: string
|
||||||
|
|
||||||
|
@Attribute(DataTypes.STRING)
|
||||||
|
@NotNull
|
||||||
|
declare password: string
|
||||||
|
|
||||||
|
@Attribute(DataTypes.STRING)
|
||||||
|
@NotNull
|
||||||
|
declare imgId: string
|
||||||
|
}
|
||||||
11
src/utils/resolvers.ts
Normal file
11
src/utils/resolvers.ts
Normal file
|
|
@ -0,0 +1,11 @@
|
||||||
|
|
||||||
|
import User from "@/sequelize/models/user";
|
||||||
|
import type { Session } from "@auth/core";
|
||||||
|
|
||||||
|
export async function getUser(session: Session | null) {
|
||||||
|
if (!session) return null
|
||||||
|
|
||||||
|
const { id } = session
|
||||||
|
const user = await User.findByPk(id)
|
||||||
|
return user
|
||||||
|
}
|
||||||
Loading…
Add table
Add a link
Reference in a new issue