forked from mxx1111/mdlook
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathshare-db.ts
More file actions
144 lines (127 loc) · 3.75 KB
/
Copy pathshare-db.ts
File metadata and controls
144 lines (127 loc) · 3.75 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
import type { ShareRow } from './share-types'
export async function getShareByUserAndPostId(
db: D1Database,
userId: string,
postId: string,
): Promise<ShareRow | null> {
return db
.prepare(`SELECT * FROM shares WHERE user_id = ? AND post_id = ?`)
.bind(userId, postId)
.first<ShareRow>()
}
export async function getShareById(db: D1Database, id: string): Promise<ShareRow | null> {
return db.prepare(`SELECT * FROM shares WHERE id = ?`).bind(id).first<ShareRow>()
}
export interface ShareListRow {
id: string
post_id: string
title: string
password_hash: string | null
created_at: number
expires_at: number | null
view_count: number
}
export async function listSharesByUserId(db: D1Database, userId: string): Promise<ShareListRow[]> {
const result = await db
.prepare(
`SELECT id, post_id, title, password_hash, created_at, expires_at, view_count
FROM shares
WHERE user_id = ?
ORDER BY created_at DESC`,
)
.bind(userId)
.all<ShareListRow>()
return result.results ?? []
}
export async function deleteShareByUserAndId(
db: D1Database,
userId: string,
id: string,
): Promise<boolean> {
const result = await db
.prepare(`DELETE FROM shares WHERE user_id = ? AND id = ?`)
.bind(userId, id)
.run()
return (result.meta.changes ?? 0) > 0
}
export async function insertShare(
db: D1Database,
row: {
id: string
postId: string
userId: string
title: string
html: string
passwordHash: string | null
createdAt: number
expiresAt: number | null
},
): Promise<void> {
await db
.prepare(
`INSERT INTO shares (id, post_id, user_id, title, html, password_hash, created_at, expires_at, view_count)
VALUES (?, ?, ?, ?, ?, ?, ?, ?, 0)`,
)
.bind(row.id, row.postId, row.userId, row.title, row.html, row.passwordHash, row.createdAt, row.expiresAt)
.run()
}
export async function updateShareContent(
db: D1Database,
row: {
userId: string
postId: string
title: string
html: string
passwordHash: string | null
expiresAt: number | null
},
): Promise<boolean> {
const result = await db
.prepare(
`UPDATE shares
SET title = ?, html = ?, password_hash = ?, expires_at = ?
WHERE user_id = ? AND post_id = ?`,
)
.bind(row.title, row.html, row.passwordHash, row.expiresAt, row.userId, row.postId)
.run()
return (result.meta.changes ?? 0) > 0
}
export async function incrementShareViewCount(db: D1Database, id: string): Promise<number> {
const row = await db
.prepare(`UPDATE shares SET view_count = view_count + 1 WHERE id = ? RETURNING view_count`)
.bind(id)
.first<{ view_count: number }>()
return row?.view_count ?? 1
}
export async function getShareRateLimitCount(
db: D1Database,
scopeKey: string,
): Promise<number> {
const hourKey = utcHourKey()
const row = await db
.prepare(`SELECT count FROM share_rate_limits WHERE scope_key = ? AND hour_key = ?`)
.bind(scopeKey, hourKey)
.first<{ count: number }>()
return row?.count ?? 0
}
export async function incrementShareRateLimit(
db: D1Database,
scopeKey: string,
): Promise<void> {
const hourKey = utcHourKey()
await db
.prepare(
`INSERT INTO share_rate_limits (scope_key, hour_key, count) VALUES (?, ?, 1)
ON CONFLICT(scope_key, hour_key) DO UPDATE SET count = count + 1`,
)
.bind(scopeKey, hourKey)
.run()
}
export function shareRateLimitRetryAfterSec(): number {
const d = new Date()
return Math.max(1, (60 - d.getUTCMinutes()) * 60 - d.getUTCSeconds())
}
function utcHourKey(): string {
const d = new Date()
return `${d.getUTCFullYear()}-${String(d.getUTCMonth() + 1).padStart(2, `0`)}-${String(d.getUTCDate()).padStart(2, `0`)}T${String(d.getUTCHours()).padStart(2, `0`)}`
}