-
Notifications
You must be signed in to change notification settings - Fork 2
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Rewrite everything for Cloudflare workers
- Loading branch information
Showing
13 changed files
with
658 additions
and
137 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -8,3 +8,5 @@ node_modules | |
dist | ||
.vercel | ||
test.md | ||
.wrangler | ||
.dev.vars |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,13 +1,11 @@ | ||
import type { VercelRequest, VercelResponse } from '@vercel/node'; | ||
import { Env } from '../lib/env'; | ||
|
||
const { CLIENT_ID, SANDBOX } = process.env; | ||
|
||
export default (req: VercelRequest, res: VercelResponse) => { | ||
export const onRequest: PagesFunction<Env> = async ({ request: req, env }) => { | ||
const state = 'v2_' + Array.from({ length: 8 }, () => Math.random().toString(36)[2]).join(''); | ||
const baseURI = SANDBOX ? 'https://ext.hml.api.enedis.fr' : 'https://mon-compte-particulier.enedis.fr'; | ||
const baseURI = env.SANDBOX ? 'https://ext.hml.api.enedis.fr' : 'https://mon-compte-particulier.enedis.fr'; | ||
|
||
return res.redirect( | ||
return Response.redirect( | ||
`${baseURI}/dataconnect/v1/oauth2/authorize` + | ||
`?client_id=${CLIENT_ID}&state=${state}&duration=P3Y&response_type=code` | ||
`?client_id=${env.CLIENT_ID}&state=${state}&duration=P3Y&response_type=code` | ||
); | ||
}; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,18 +1,24 @@ | ||
import { VercelRequest, VercelResponse } from '@vercel/node'; | ||
import { generateToken } from '../lib/auth'; | ||
import { Env } from '../lib/env'; | ||
import { z } from 'zod'; | ||
import pino from 'pino'; | ||
const logger = pino(); | ||
|
||
export default async (req: VercelRequest, res: VercelResponse) => { | ||
export const onRequest: PagesFunction<Env> = async ({ request: req, env }) => { | ||
try { | ||
const queryPRMs = z.string().parse(req.query.usage_point_id).split(/[,;]/g); | ||
const { searchParams } = new URL(req.url); | ||
const queryPRMs = z.string().parse(searchParams.get('usage_point_id')).split(/[,;]/g); | ||
|
||
const authToken = generateToken(queryPRMs); | ||
res.setHeader('Set-Cookie', `conso-token=${authToken}; SameSite=Strict; Path=/`); | ||
res.redirect('/token'); | ||
const authToken = await generateToken(queryPRMs, env.JWT_SECRET); | ||
return new Response('/token', { | ||
status: 302, | ||
headers: { | ||
Location: '/token', | ||
'Set-Cookie': `conso-token=${authToken}; SameSite=Strict; Path=/`, | ||
}, | ||
}); | ||
} catch (e) { | ||
logger.error({ message: 'cannot generate Auth token', error: e }); | ||
res.status(500).send({ status: 500, message: 'internal server error' }); | ||
return Response.json({ status: 500, message: 'internal server error' }, { status: 500 }); | ||
} | ||
}; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,9 @@ | ||
{ | ||
"compilerOptions": { | ||
"target": "esnext", | ||
"module": "esnext", | ||
"lib": ["esnext"], | ||
"types": ["@cloudflare/workers-types"], | ||
"moduleResolution": "node" | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,10 @@ | ||
import { KVNamespace } from '@cloudflare/workers-types'; | ||
|
||
export interface Env { | ||
BASE_URL: string; | ||
JWT_SECRET: string; | ||
CLIENT_ID: string; | ||
CLIENT_SECRET: string; | ||
SANDBOX: string | undefined; | ||
CONSO_API: KVNamespace; | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,33 +1,42 @@ | ||
import axios from 'axios'; | ||
import * as qs from 'qs'; | ||
import pino from 'pino'; | ||
import { Env } from './env'; | ||
|
||
const logger = pino(); | ||
const { BASE_URL, CLIENT_ID, CLIENT_SECRET } = process.env; | ||
|
||
let token: string; | ||
let tokenExpiration: number; | ||
const KV_KEY = 'access_token'; | ||
|
||
export async function getAPIToken(): Promise<string> { | ||
if (token && new Date().getTime() < tokenExpiration) { | ||
export async function getAPIToken(env: Env): Promise<string> { | ||
const token = await env.CONSO_API.get(KV_KEY); | ||
if (token) { | ||
return token; | ||
} | ||
|
||
const { data } = await axios({ | ||
method: 'post', | ||
url: `${BASE_URL}/oauth2/v3/token?${qs.stringify({ | ||
const response = await fetch( | ||
`${env.BASE_URL}/oauth2/v3/token?${qs.stringify({ | ||
grant_type: 'client_credentials', | ||
client_id: CLIENT_ID, | ||
client_secret: CLIENT_SECRET, | ||
client_id: env.CLIENT_ID, | ||
client_secret: env.CLIENT_SECRET, | ||
})}`, | ||
headers: { | ||
'Content-Type': 'application/x-www-form-urlencoded', | ||
}, | ||
}); | ||
{ | ||
method: 'POST', | ||
headers: { | ||
'Content-Type': 'application/x-www-form-urlencoded', | ||
}, | ||
} | ||
); | ||
|
||
if (!response.ok) { | ||
return Promise.reject(response); | ||
} | ||
|
||
const data: { access_token: string } = await response.json(); | ||
logger.info({ message: 'token refreshed', token: data.access_token }); | ||
|
||
token = data.access_token; | ||
tokenExpiration = new Date().getTime() + 3 * 3600 * 1000; // token expiration is 3 hours later | ||
// Save in KV store | ||
await env.CONSO_API.put(KV_KEY, data.access_token, { | ||
expirationTtl: 3 * 3600, // token expiration is 3 hours later | ||
}); | ||
|
||
return token; | ||
return data.access_token; | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,36 +1,39 @@ | ||
{ | ||
"private": true, | ||
"scripts": { | ||
"build": "nuxt build", | ||
"dev": "nuxt dev", | ||
"generate": "nuxt generate", | ||
"serve": "wrangler pages dev dist --kv=CONSO_API", | ||
"preview": "nuxt preview", | ||
"postinstall": "nuxt prepare", | ||
"prepare": "husky install", | ||
"ipban": "zx ./.github/scripts/ipban.mjs" | ||
}, | ||
"prettier": "@bokub/prettier-config", | ||
"packageManager": "[email protected]", | ||
"devDependencies": { | ||
"@bokub/prettier-config": "^2.1.0", | ||
"@cloudflare/workers-types": "^4.20240620.0", | ||
"@nuxt-themes/elements": "^0.5.2", | ||
"@nuxt-themes/typography": "^0.4.3", | ||
"@nuxt/content": "^2.3.0", | ||
"@nuxtjs/tailwindcss": "^6.2.0", | ||
"@types/canvas-confetti": "^1.6.0", | ||
"@types/jsonwebtoken": "^9.0.1", | ||
"@types/qs": "^6.9.7", | ||
"@vercel/node": "^2.8.15", | ||
"axios": "^1.3.6", | ||
"canvas-confetti": "^1.6.0", | ||
"chart.js": "^4.2.1", | ||
"husky": "^8.0.0", | ||
"jsonwebtoken": "^9.0.0", | ||
"jose": "^5.6.3", | ||
"nuxt": "^3.4.0", | ||
"nuxt-umami": "^2.5.1", | ||
"pino": "^8.8.0", | ||
"prettier": "^2.8.3", | ||
"pretty-quick": "^3.1.3", | ||
"qs": "^6.11.0", | ||
"typescript": "^5.5.3", | ||
"wrangler": "^3.63.2", | ||
"zod": "^3.20.2", | ||
"zx": "^7.2.3" | ||
} | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,4 +1,5 @@ | ||
{ | ||
// https://nuxt.com/docs/guide/concepts/typescript | ||
"exclude": ["api/**/*"], | ||
"extends": "./.nuxt/tsconfig.json" | ||
} |
This file was deleted.
Oops, something went wrong.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1 @@ | ||
compatibility_date = "2024-07-01" |
Oops, something went wrong.