Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Feature/user setting #25

Closed
wants to merge 99 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
99 commits
Select commit Hold shift + click to select a range
620951d
feat: union layout page
winverse Dec 8, 2023
6a786ee
fix: handle not found user
winverse Dec 8, 2023
2e43bb3
Merge branch 'feature/velog-page' into feature/user-setting
winverse Dec 8, 2023
670fbea
feat: get UserProfile
winverse Dec 8, 2023
8bc387c
Merge branch 'feature/velog-page' into feature/user-setting
winverse Dec 13, 2023
c6f9023
feat: create component for setting page
winverse Dec 13, 2023
5cf0755
Merge branch 'feature/velog-page' into feature/user-setting
winverse Dec 13, 2023
7c72453
feat: complete Setting page component
winverse Dec 14, 2023
6e6296e
WIP: file upload api
winverse Dec 14, 2023
7a18ba7
feat: add validation
winverse Dec 15, 2023
9789bf3
feat: add validator compiler plugin
winverse Dec 15, 2023
4d6c0eb
feat: implement create url
winverse Dec 15, 2023
d5e7cf1
chore: remove a line
winverse Dec 15, 2023
5480275
WIP: imageService
winverse Dec 15, 2023
20efd69
Merge remote-tracking branch 'origin/feature/velog-page' into feature…
winverse Dec 17, 2023
13016dc
feat: implement imageService
winverse Dec 17, 2023
e9a8f69
chore: add example .env
winverse Dec 17, 2023
751df69
remove
winverse Dec 17, 2023
aa98544
add
winverse Dec 17, 2023
33a843d
feat: file upload
winverse Dec 17, 2023
4abce78
feat: implement user setting api
winverse Dec 18, 2023
a9233a3
feat: implement user setting query api
winverse Dec 18, 2023
d1094ca
Merge branch 'feature/velog-page' into feature/user-setting
winverse Dec 18, 2023
7b66374
fix: build error
winverse Dec 18, 2023
2217415
Merge remote-tracking branch 'origin/feature/velog-page' into feature…
winverse Dec 18, 2023
f65f952
feat: implement setting gql
winverse Dec 18, 2023
a67d638
chore: move generated file
winverse Dec 18, 2023
182ee0b
feat: remove initeQuerykey
winverse Dec 18, 2023
00e5bf2
fix: build error
winverse Dec 18, 2023
d30ea9b
fix: change immediate execute key name
winverse Dec 18, 2023
f691e25
fix: change layout
winverse Dec 18, 2023
b25365e
WIP: user setting page
winverse Dec 19, 2023
f23b778
chore: tsx version up
winverse Dec 20, 2023
c35a915
Merge branch 'feature/velog-page' into feature/user-setting
winverse Dec 21, 2023
e9fd26e
Merge branch 'feature/velog-page' into feature/user-setting
winverse Dec 21, 2023
f58585a
fix: build error
winverse Dec 21, 2023
e5ac201
add packages
winverse Dec 21, 2023
312b668
Merge branch 'feature/velog-page' into feature/user-setting
winverse Dec 22, 2023
4b281c8
refactor: cron plugin
winverse Dec 22, 2023
fb2ce65
wip: connection api
winverse Dec 22, 2023
978c5ff
Merge branch 'fix/feed-action' into feature/user-setting
winverse Dec 27, 2023
cf6fa2a
fix: merge build error
winverse Dec 27, 2023
fe293e8
Merge branch 'feature/ads-banner' into feature/user-setting
winverse Dec 28, 2023
a495553
WIP: image upload
winverse Dec 28, 2023
84a8d5c
feat: image upload with progress
winverse Dec 29, 2023
7a2ddda
fix: bindclass func
winverse Dec 29, 2023
ea0588a
feat: change email
winverse Jan 1, 2024
f292295
fix: markdown render bug
winverse Jan 1, 2024
e7af7d4
chore: remove console
winverse Jan 1, 2024
f13d81d
feat: change email
winverse Jan 1, 2024
37dbdbf
Merge remote-tracking branch 'origin/main' into feature/user-setting
winverse Jan 1, 2024
2433041
fix: xss issue
winverse Jan 1, 2024
6d3c2b1
feat: setup email rules
winverse Jan 1, 2024
9027e9a
feat: unregister user
winverse Jan 1, 2024
4a86859
feat: handle not found usermeta
winverse Jan 1, 2024
5e8e90c
feat: implement theme setting
winverse Jan 2, 2024
679211b
feat: find target posts
winverse Jan 3, 2024
bec3ac2
chore: add packages
winverse Jan 3, 2024
bca51d4
feat: handle privated user info
winverse Jan 3, 2024
e993e9c
feat: create discord
winverse Jan 3, 2024
7eece66
feat: implement private spam user posts
winverse Jan 3, 2024
2a7d8c2
feat: set black list in redis
winverse Jan 3, 2024
378829c
chore: change ordering
winverse Jan 3, 2024
46944a2
feat: send message with handled post id
winverse Jan 3, 2024
ad53e28
Merge pull request #19 from velog-io/feature/black_user_posts
winverse Jan 4, 2024
b9535a3
feat: check gql file
winverse Jan 4, 2024
ac140fa
chore: error handle for invalid ext file name
winverse Jan 4, 2024
68dc987
feat: remove unused line
winverse Jan 4, 2024
d5017e4
fix: check gql file by server type
winverse Jan 4, 2024
20354f0
feat: implement restore posts
winverse Jan 4, 2024
f0d05ce
Merge pull request #20 from velog-io/feature/check-gql-files
winverse Jan 4, 2024
5c861d0
Merge pull request #21 from velog-io/feature/restore-posts
winverse Jan 4, 2024
4072173
chore: handle not found data
winverse Jan 4, 2024
6fdd9c4
Merge branch 'feature/restore-posts' into feature/user-setting
winverse Jan 4, 2024
d4d69d9
Merge branch 'main' into feature/user-setting
winverse Jan 5, 2024
39f1acb
chore: remove console
winverse Jan 5, 2024
97a5f84
feat: remove color scheme
winverse Jan 5, 2024
a97edab
feat: support mobile browser header color
winverse Jan 5, 2024
f74787a
fix: theme seletor
winverse Jan 5, 2024
9c668da
fix: update css for theme selector
winverse Jan 5, 2024
bf6e525
fix: theme selector
winverse Jan 5, 2024
d7dad72
fix: theme color bug
winverse Jan 5, 2024
b1442f4
feat: support handle apple mobile status
winverse Jan 5, 2024
76d50af
fix: change apple mobile dark mode status color
winverse Jan 5, 2024
626ce3c
chore: add console
winverse Jan 8, 2024
7152e56
chore: change script command
winverse Jan 8, 2024
88f75bc
fix: apply apple status color
winverse Jan 8, 2024
7fae9e9
fix: from black to block
winverse Jan 8, 2024
170a06f
fix: handle color
winverse Jan 8, 2024
0445a84
WIP: handle setting page caching
winverse Jan 8, 2024
21d91e7
fix: setting page bug
winverse Jan 8, 2024
59ec3e0
fix: not found change-email code message
winverse Jan 8, 2024
ada52a5
fix: theme picker bug
winverse Jan 8, 2024
ca76307
fix: build error
winverse Jan 9, 2024
6f9d59d
fix: build error
winverse Jan 9, 2024
b0594f6
fix: remove viewport
winverse Jan 9, 2024
a0c0084
fix: add spam account username filter
winverse Jan 9, 2024
8c34936
fix: trending-writer display name color
winverse Jan 9, 2024
5ae386d
fix: delete feed query
winverse Jan 9, 2024
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
3 changes: 2 additions & 1 deletion .vscode/settings.json
Original file line number Diff line number Diff line change
Expand Up @@ -52,5 +52,6 @@
"C_Cpp_Runner.useLeakSanitizer": false,
"C_Cpp_Runner.showCompilationTime": false,
"C_Cpp_Runner.useLinkTimeOptimization": false,
"C_Cpp_Runner.msvcSecureNoWarnings": false
"C_Cpp_Runner.msvcSecureNoWarnings": false,
"workbench.colorCustomizations": {}
}
3 changes: 2 additions & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,8 @@
"email": "[email protected]"
},
"keywords": [
"velog"
"velog",
"blog"
],
"devDependencies": {
"husky": "^8.0.0",
Expand Down
2 changes: 1 addition & 1 deletion packages/velog-cron/src/common/errors/BadRequestErrors.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,6 @@ import { HttpError } from './HttpError.js'

export class BadRequestError extends HttpError {
constructor(message = 'BAD_REQUEST') {
super(message, 400, 'BadRequest')
super('bad request', message, 400)
}
}
2 changes: 1 addition & 1 deletion packages/velog-cron/src/common/errors/ConfilctError.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,6 @@ import { HttpError } from './HttpError.js'

export class ConfilctError extends HttpError {
constructor(message = 'CONFILCT') {
super(message, 409, 'Confilct')
super('confilct', message, 409)
}
}
2 changes: 1 addition & 1 deletion packages/velog-cron/src/common/errors/ForbiddenError.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,6 @@ import { HttpError } from './HttpError.js'

export class ForbiddenError extends HttpError {
constructor(message = 'FORBIDDEN') {
super(message, 403, 'Forbidden')
super('forbidden', message, 403)
}
}
2 changes: 1 addition & 1 deletion packages/velog-cron/src/common/errors/HttpError.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ export class HttpError extends Error {
message
statusCode
name
constructor(message: string, statusCode: number, name: string) {
constructor(name: string, message: string, statusCode: number) {
super()
this.message = message
this.statusCode = statusCode
Expand Down
2 changes: 1 addition & 1 deletion packages/velog-cron/src/common/errors/NotfoundError.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,6 @@ import { HttpError } from './HttpError.js'

export class NotFoundError extends HttpError {
constructor(message = 'NOT_FOUND') {
super(message, 404, 'NotFound')
super('not found', message, 404)
}
}
2 changes: 1 addition & 1 deletion packages/velog-cron/src/common/errors/UnauthorizedError.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,6 @@ import { HttpError } from './HttpError.js'

export class UnauthorizedError extends HttpError {
constructor(message = 'Unauthorized') {
super(message, 401, 'Unauthorized')
super('unauthorized', message, 401)
}
}
47 changes: 24 additions & 23 deletions packages/velog-cron/src/common/plugins/globals/cronPlugin.ts
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,6 @@ const cronPlugin: FastifyPluginCallback = async (fastfiy, opts, done) => {
name: 'generate trending writers every day',
cronTime: '0 5 * * *', // every day at 05:00 (5:00 AM)
jobService: generateTrendingWritersJob,
param: undefined,
},
{
name: 'posts score calculation in every day',
Expand All @@ -30,13 +29,11 @@ const cronPlugin: FastifyPluginCallback = async (fastfiy, opts, done) => {
name: 'delete feed in every hour',
cronTime: '10 * * * *', // every hour at 10 minutes
jobService: deleteFeedJob,
param: undefined,
},
{
name: 'generate feeds in every 1 minute',
cronTime: '*/1 * * * *', // every 1 minute
jobService: generateFeedJob,
param: undefined,
},
{
name: 'posts score calculation in every 5 minutes',
Expand All @@ -55,23 +52,27 @@ const cronPlugin: FastifyPluginCallback = async (fastfiy, opts, done) => {
})
}

// for test
if (ENV.dockerEnv !== 'production') {
const immediateRunJobs = jobDescription.filter((job) => !!job.isImmediate)
await Promise.all(immediateRunJobs.map(createTick))
try {
// for Test
if (ENV.dockerEnv !== 'production') {
const immediateRunJobs = jobDescription.filter((job) => !!job.isImmediateExecute)
await Promise.all(immediateRunJobs.map(createTick))
}

if (ENV.dockerEnv === 'production') {
const crons = jobDescription.map(createJob)
await Promise.all(
crons.map((cron) => {
console.log(`${cron.name} is registered`)
cron.start()
}),
)
}
} catch (error) {
console.error('Error initializing cron jobs:', error)
} finally {
done()
}

if (ENV.dockerEnv === 'production') {
const crons = jobDescription.map(createJob)
await Promise.all(
crons.map((cron) => {
console.log(`${cron.name} is registered`)
cron.start()
}),
)
}

done()
}

export default cronPlugin
Expand All @@ -93,16 +94,16 @@ type JobDescription = NeedParamJobService | NotNeedParamJobService
type NeedParamJobService = {
name: string
cronTime: string
param: number
isImmediate?: boolean
param: any
isImmediateExecute?: boolean
jobService: CalculatePostScoreJob
}

type NotNeedParamJobService = {
name: string
cronTime: string
param: undefined
isImmediate?: boolean
param?: undefined
isImmediateExecute?: boolean
jobService: GenerateFeedJob | GenerateTrendingWritersJob | DeleteFeedJob
}

Expand Down
6 changes: 6 additions & 0 deletions packages/velog-cron/src/services/FeedService/index.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
import { DbService } from '@lib/db/DbService.js'
import { UtilsService } from '@lib/utils/UtilsService'
import { FollowUserService } from '@services/FollowUserService/index.js'
import { subHours } from 'date-fns'

import { injectable, singleton } from 'tsyringe'

Expand All @@ -12,6 +14,7 @@ interface Service {
export class FeedService implements Service {
constructor(
private readonly db: DbService,
private readonly utils: UtilsService,
private readonly followUserService: FollowUserService,
) {}
public async createFeed({ followingId, postId }: CreateFeedArgs): Promise<void> {
Expand All @@ -32,6 +35,9 @@ export class FeedService implements Service {
return await this.db.feed.deleteMany({
where: {
is_deleted: true,
created_at: {
lte: subHours(this.utils.now, 1),
},
},
})
}
Expand Down
25 changes: 25 additions & 0 deletions packages/velog-scripts/.eslintrc.cjs
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
module.exports = {
parser: '@typescript-eslint/parser',
parserOptions: {
project: './tsconfig.json',
sourceType: 'module',
tsconfigRootDir: __dirname,
},
plugins: ['@typescript-eslint', 'prettier'],
extends: ['plugin:@typescript-eslint/recommended', 'plugin:prettier/recommended'],
root: true,
env: {
node: true,
jest: true,
},
rules: {
'prettier/prettier': ['error', { semi: false, singleQuote: true }],
'@typescript-eslint/interface-name-prefix': 'off',
'@typescript-eslint/explicit-function-return-type': 'off',
'@typescript-eslint/explicit-module-boundary-types': 'off',
'@typescript-eslint/no-explicit-any': 'off',
'@typescript-eslint/no-non-null-assertion': 'off',
'@typescript-eslint/no-empty-interface': 'off',
'@typescript-eslint/no-unused-vars': ['error', { ignoreRestSiblings: true }],
},
}
4 changes: 4 additions & 0 deletions packages/velog-scripts/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
/prisma

/data/*
!/data/.gitkeep
Empty file.
5 changes: 5 additions & 0 deletions packages/velog-scripts/env/.env.example
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
DATABASE_URL=
DISCORD_BOT_TOKEN=
DISCORD_PRIVATE_POSTS_CHANNEL_ID=
REDIS_HOST=
SPAM_ACCOUNT_DISPLAY_NAME=
27 changes: 27 additions & 0 deletions packages/velog-scripts/env/env.mts
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
import { z } from 'zod'
import dotenv from 'dotenv'
import path from 'path'

if (process.env.NODE_ENV === 'production') {
throw new Error('This Script only allowed in Development environment')
}

dotenv.config({ path: path.resolve(process.cwd(), '.env') })

const env = z.object({
spamAccountDisplayName: z.array(z.string()).min(1),
databaseUrl: z.string(),
discordBotToken: z.string(),
discordPrivatePostsChannelId: z.string(),
redisHost: z.string(),
restorePostsUsername: z.string().optional(),
})

export const ENV = env.parse({
spamAccountDisplayName: (process.env.SPAM_ACCOUNT_DISPLAY_NAME ?? '')?.split(',').filter(Boolean),
databaseUrl: process.env.DATABASE_URL,
discordBotToken: process.env.DISCORD_BOT_TOKEN,
discordPrivatePostsChannelId: process.env.DISCORD_PRIVATE_POSTS_CHANNEL_ID,
redisHost: process.env.REDIS_HOST,
restorePostsUsername: process.env.RESTORE_POSTS_USERNAME,
})
6 changes: 6 additions & 0 deletions packages/velog-scripts/lib/db/DbService.mts
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
import { PrismaClient } from '@prisma/client'
import { injectable, singleton } from 'tsyringe'

@injectable()
@singleton()
export class DbService extends PrismaClient {}
47 changes: 47 additions & 0 deletions packages/velog-scripts/lib/discord/DiscordService.mts
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
import { injectable, singleton } from 'tsyringe'
import { Client, GatewayIntentBits } from 'discord.js'
import { ENV } from '../../env/env.mjs'

@injectable()
@singleton()
export class DiscordService {
private client!: Client
construct() {}
public connection(): Promise<Client> {
return new Promise((resolve) => {
this.client = new Client({
intents: [GatewayIntentBits.MessageContent],
})

this.client.on('ready', () => {
console.log('Discord Client ready!')
resolve(this.client)
})

this.client.login(ENV.discordBotToken)
})
}
public sendMessage(channelId: string, message: string) {
return new Promise(async (resolve, reject) => {
try {
const isReady = this.client.isReady()

if (!isReady) {
throw new Error('Discord bot is not ready')
}

const channel = await this.client.channels.fetch(channelId)

if (channel?.isTextBased()) {
await channel.send(message)
} else {
throw new Error('Wrong channel type')
}
resolve('Message sent successfully!')
} catch (error) {
reject('Failed to send meesage')
throw error
}
})
}
}
51 changes: 51 additions & 0 deletions packages/velog-scripts/lib/redis/RedisService.mts
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
import { injectable, singleton } from 'tsyringe'
import Redis from 'ioredis'
import { ENV } from '../../env/env.mjs'

interface Service {
get setName(): SetName
}

@injectable()
@singleton()
export class RedisService extends Redis implements Service {
constructor() {
super({ port: 6379, host: ENV.redisHost })
}

async connection(): Promise<string> {
return new Promise((resolve) => {
this.connect(() => {
resolve(`Redis connection established to ${ENV.redisHost}`)
})
})
}

get setName() {
return {
blockList: 'set:blockList',
}
}

public async addBlockList(username: string) {
try {
const keyname = this.setName.blockList
await this.sadd(keyname, username)
} catch (error) {
throw error
}
}

public async readBlockList() {
try {
const keyname = this.setName.blockList
return await this.smembers(keyname)
} catch (error) {
throw error
}
}
}

type SetName = {
blockList: string
}
Loading
Loading