-
Notifications
You must be signed in to change notification settings - Fork 8
/
Copy pathapi.ts
186 lines (164 loc) · 5.44 KB
/
api.ts
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
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
import Axios, { type AxiosError } from 'axios'
import cookie from 'cookie'
export const apiEndpoints = {
USER_SESSION: '/api/v2/ooniauth/user-session',
USER_LOGIN: '/api/v2/ooniauth/user-login',
RUN_LINK: '/api/v2/oonirun/links',
RUN_LINK_REVISION:
'/api/v2/oonirun/links/:linkId/full-descriptor/:revisionNr',
}
const SEVEN_DAYS_IN_SECONDS = 7 * 24 * 60 * 60
const setCookie = (tokenDetails: string) => {
return `token=${tokenDetails}; Path=/; Max-Age=${SEVEN_DAYS_IN_SECONDS}; SameSite=Strict; Secure`
}
const getBearerToken = () => {
return typeof document !== 'undefined' && cookie.parse(document.cookie)?.token
? JSON.parse(cookie.parse(document.cookie)?.token)?.token
: null
}
export const getTokenCreatedAt = () => {
return typeof document !== 'undefined' && cookie.parse(document.cookie)?.token
? JSON.parse(cookie.parse(document.cookie)?.token)?.created_at
: null
}
export const getUserEmail = () => {
return typeof document !== 'undefined' && cookie.parse(document.cookie)?.token
? JSON.parse(cookie.parse(document.cookie)?.token)?.email_address
: null
}
const axios = Axios.create({ withCredentials: false })
type Config = {
// biome-ignore lint/suspicious/noExplicitAny: <explanation>
[key: string]: any
method?: string
}
export const getAPI = async (endpoint: string, config: Config = {}) => {
const bearerToken = getBearerToken()
return await axios
.request({
method: config.method ?? 'GET',
url: endpoint,
...(bearerToken && {
headers: { Authorization: `Bearer ${bearerToken}` },
}),
...config,
})
.then((res) => res.data)
.catch((e: Error | AxiosError) => {
if (Axios.isAxiosError(e)) {
const error = JSON.stringify(
e?.response?.data?.error || e?.response?.data?.detail || e?.message,
)
throw new Error(error)
}
throw new Error(e.message)
})
}
const postAPI = async (endpoint: string, data = {}, params = {}) => {
return await getAPI(endpoint, { method: 'POST', data, params })
}
const putAPI = async (endpoint: string, data = {}, params = {}) => {
return await getAPI(endpoint, { method: 'PUT', data, params })
}
// biome-ignore lint/suspicious/noExplicitAny: <explanation>
export const createRunLink = (data: any, params = {}) => {
return postAPI(apiEndpoints.RUN_LINK, data, params)
}
// biome-ignore lint/suspicious/noExplicitAny: <explanation>
export const updateRunLink = (id: string, data: any) => {
return putAPI(`${apiEndpoints.RUN_LINK}/${id}`, data)
}
export const getRunLink = (id: string, config = {}) => {
return getAPI(`${apiEndpoints.RUN_LINK}/${id}`, config)
}
export const getRunLinkRevision = (
id: string,
revision: string,
config = {},
) => {
return getAPI(
apiEndpoints.RUN_LINK_REVISION.replace(':linkId', id).replace(
':revisionNr',
revision,
),
config,
)
}
export const getList = (params = {}, config = {}) => {
return getAPI(apiEndpoints.RUN_LINK, { ...config, params })
}
export const registerUser = async (
email_address: string,
redirectUrl = 'https://run.ooni.org',
) => {
// current testing setup does not enable us to check process.env.NODE_ENV (it's set to production
// in headless mode), therefore custom NEXT_PUBLIC_IS_TEST_ENV is used
const redirectTo =
process.env.NODE_ENV === 'development' ||
process.env.NEXT_PUBLIC_IS_TEST_ENV
? `https://run.test.ooni.org${new URL(redirectUrl)?.pathname || ''}`
: redirectUrl
return await postAPI(apiEndpoints.USER_LOGIN, {
email_address,
redirect_to: redirectTo,
})
}
export const loginUser = (login_token: string) => {
return postAPI(apiEndpoints.USER_SESSION, { login_token }).then((data) => {
console.log('data', data)
const tokenDetails = JSON.stringify({
token: data?.session_token,
email_address: data?.email_address,
created_at: Date.now(),
})
document.cookie = setCookie(tokenDetails)
return data
})
}
export const refreshToken = () => {
const email_address = getUserEmail()
return postAPI(apiEndpoints.USER_SESSION).then((data) => {
const tokenDetails = JSON.stringify({
token: data.login_token,
email_address,
created_at: Date.now(),
})
document.cookie = setCookie(tokenDetails)
})
}
export const fetcher = async (url: string, params?: object) => {
try {
const res = await getAPI(url, params)
return res
} catch (e: unknown) {
if (Axios.isAxiosError(e)) {
throw new Error(e?.response?.data?.error)
// error.info = e?.response?.statusText
// error.status = e?.response?.status
}
const error = e as Error
throw new Error(error.message)
}
}
export const postFetcher = async (url: string) => {
try {
const res = await postAPI(url)
return res
} catch (e: unknown) {
if (Axios.isAxiosError(e)) {
throw new Error(e?.response?.data?.error)
}
const error = e as Error
throw new Error(error.message)
}
}
// export const customErrorRetry = (error, key, config, revalidate, opts) => {
// // This overrides the default exponential backoff algorithm
// // Instead it uses the `errorRetryInterval` and `errorRetryCount` configuration to
// // limit the retries
// const maxRetryCount = config.errorRetryCount
// if (maxRetryCount !== undefined && opts.retryCount > maxRetryCount) return
// // Never retry on 4xx errors
// if (Math.floor(error.status / 100) === 4) return
// setTimeout(revalidate, config.errorRetryInterval, opts)
// }