-
Notifications
You must be signed in to change notification settings - Fork 0
/
index.js
149 lines (118 loc) · 3.52 KB
/
index.js
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
145
146
147
148
149
import { PostgrestClient } from '@supabase/postgrest-js'
import { Router } from 'itty-router'
import * as jwt from 'jsonwebtoken'
const client = new PostgrestClient(POSTGREST_ENDPOINT, {
fetch: (...args) => fetch(...args),
})
const router = Router({ base: '/api' })
// Middleware for route protection
const requireUser = (request) => {
const { query } = request
const token = query.accessToken
if (!token) {
return new Response('Not Authenticated', { status: 401 })
}
try {
const decoded = jwt.verify(token, JWT_SECRET)
if (!decoded.user) {
return new Response('Invalid token', { status: 401 })
}
} catch (error) {
return new Response('Error verifying token', { status: 500 })
}
}
// @route GET api/stocks
// @desc Get a list of all stocks
// @access Public
router.get('/stocks', async () => {
const { data, error } = await client.from('stocks').select()
if (error) throw error
return new Response(JSON.stringify({ stocks: data }), {
headers: { 'content-type': 'application/json' },
})
})
// @route GET api/stocks/:id
// @desc Get a the stock by id
// @access Public
router.get('/stocks/:id', async ({ params }) => {
const { id } = params
const { data, error } = await client
.from('stocks')
.select()
.eq('id', id)
if (error) throw error
const stock = data.length ? data[0] : null
// Update views
if (stock) {
const { error } = await client
.from('stocks')
.update({ views: stock.views + 1 })
.match({ id: stock.id })
if (error) throw error
}
return new Response(JSON.stringify({ stock }), {
headers: { 'content-type': 'application/json' },
status: stock ? 200 : 404
})
})
// @route POST api/stocks
// @desc Add a new stock
// @access Private
router.post('/stocks', requireUser, async (request) => {
const stockData = await request.json()
const { data: stock, error } = await client
.from('stocks')
.insert([stockData])
if (error) throw error
return new Response(JSON.stringify({ stock }), {
headers: { 'content-type': 'application/json' },
})
})
// @route POST api/auth/login
// @desc Logs in user
// @access Public
router.post('/auth/login', async (request) => {
const { username, password } = await request.json()
const { data, error } = await client
.from('users')
.select()
.eq('username', username)
.eq('pass', password)
if (error) throw error
const user = data.length ? data[0] : null
if (!user) {
return new Response("User Not Found", { status: 401 })
}
const payload = {
user: {
id: user.id,
},
}
const token = jwt.sign(payload, JWT_SECRET, { expiresIn: 360000 })
return new Response(JSON.stringify({ token }), { status: 200 })
});
// @route PUT api/stocks/:id
// @desc Edit a stock
// @access Private
router.put('/stocks/:id', requireUser, async (request) => {
const id = request.params.id
const stockData = await request.json()
const { data: stock, error } = await client
.from('stocks')
.update({
...stockData,
'edited_by': request.user.id
})
.match({ id })
if (error) throw error
return new Response(JSON.stringify({ stock }), {
headers: { 'content-type': 'application/json' },
})
})
// @route *
// @desc Any other route will return Not Found with 404 Status
router.all('*', () => new Response("Not Found", { status: 404 }))
addEventListener('fetch', event => {
console.log('headers', JSON.stringify(event.request.headers));
event.respondWith(router.handle(event.request))
})