This repository has been archived by the owner on Jun 27, 2024. It is now read-only.
-
-
Notifications
You must be signed in to change notification settings - Fork 1
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
refactor: move all accessories to root (#177)
* refactor: move all accessories to root * fix issues
- Loading branch information
1 parent
a920466
commit fcc380e
Showing
7 changed files
with
565 additions
and
41 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
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,92 @@ | ||
// Copyright 2023 Samuel Kopp. All rights reserved. Apache-2.0 license. | ||
import { | ||
decode, | ||
encode, | ||
} from 'https://deno.land/std@0.198.0/encoding/base64.ts' | ||
import { | ||
create, | ||
getNumericDate, | ||
Payload as JwtPayload, | ||
verify as _verify, | ||
VerifyOptions, | ||
} from 'https://deno.land/x/djwt@v2.8/mod.ts' | ||
|
||
interface Payload { | ||
iss?: string | ||
sub?: string | ||
aud?: string[] | string | ||
/** | ||
* A `Date` object or a `number` (in seconds) when the JWT will expire. | ||
*/ | ||
exp?: Date | number | ||
/** | ||
* A `Date` object or a `number` (in seconds) until which the JWT will be invalid. | ||
*/ | ||
nbf?: Date | number | ||
iat?: number | ||
jti?: string | ||
[key: string]: unknown | ||
} | ||
|
||
export async function createKey() { | ||
const key = await crypto.subtle.generateKey( | ||
{ name: 'HMAC', hash: 'SHA-512' }, | ||
true, | ||
['sign', 'verify'], | ||
) | ||
|
||
const exportedKey = await crypto.subtle.exportKey('raw', key) | ||
|
||
return encode(exportedKey) | ||
} | ||
|
||
export function importKey(key: string) { | ||
return crypto.subtle.importKey( | ||
'raw', | ||
decode(key).buffer, | ||
{ name: 'HMAC', hash: 'SHA-512' }, | ||
true, | ||
['sign', 'verify'], | ||
) | ||
} | ||
|
||
/** | ||
* Sign a payload. | ||
*/ | ||
// deno-lint-ignore ban-types | ||
export async function sign<T extends Record<string, unknown> = {}>( | ||
payload: T & Payload, | ||
secret: string | CryptoKey, | ||
) { | ||
const key = typeof secret === 'string' ? await importKey(secret) : secret | ||
|
||
const { exp, nbf, ...rest } = payload | ||
|
||
return await create({ alg: 'HS512', typ: 'JWT' }, { | ||
...(exp && { exp: getNumericDate(exp) }), | ||
...(nbf && { nbf: getNumericDate(nbf) }), | ||
...rest, | ||
}, key) | ||
} | ||
|
||
/** | ||
* Verify the validity of a JWT. | ||
*/ | ||
export async function verify<T extends Record<string, unknown> = Payload>( | ||
token: string, | ||
secret: string | CryptoKey, | ||
options?: VerifyOptions, | ||
) { | ||
try { | ||
const key = typeof secret === 'string' ? await importKey(secret) : secret | ||
|
||
return await _verify(token, key, options) as JwtPayload & T | ||
} catch (_err) { | ||
return | ||
} | ||
} | ||
|
||
export default { | ||
sign, | ||
verify, | ||
} |
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,146 @@ | ||
// Copyright 2023 Samuel Kopp. All rights reserved. Apache-2.0 license. | ||
import { IncomingRequestCfProperties } from 'https://cdn.jsdelivr.net/npm/@cloudflare/workers-types@4.20230814.0/index.ts' | ||
import { Context } from './context.ts' | ||
|
||
type CloudflareRequest = Request & { | ||
cf: IncomingRequestCfProperties | ||
} | ||
|
||
/** | ||
* Inspect the geolocation data of the incoming request. | ||
* | ||
* You must either deploy your app to [Cloudflare Workers](https://developers.cloudflare.com/workers/runtime-apis/request/#incomingrequestcfproperties) or use [Cloudflare as a proxy](https://developers.cloudflare.com/support/network/configuring-ip-geolocation/) to use the `LocationData` API. | ||
*/ | ||
export class LocationData { | ||
#c: Context | ||
|
||
constructor(c: Context) { | ||
this.#c = c | ||
} | ||
|
||
/** | ||
* The city the request originated from. | ||
* | ||
* @example 'Austin' | ||
*/ | ||
get city() { | ||
const city = (this.#c.req.raw as CloudflareRequest).cf?.city | ||
|
||
if (!city && this.#c.__app.proxy === 'cloudflare') { | ||
return this.#c.req.headers['cf-ipcity'] | ||
} | ||
|
||
return city | ||
} | ||
|
||
/** | ||
* If known, the ISO 3166-2 name for the first level region associated with the IP address of the incoming request. | ||
* | ||
* @example 'Texas' | ||
*/ | ||
get region() { | ||
return (this.#c.req.raw as CloudflareRequest).cf?.region | ||
} | ||
|
||
/** | ||
* The [ISO 3166-1 Alpha 2](https://www.iso.org/iso-3166-country-codes.html) country code the request originated from. | ||
* | ||
* If you're using CLoudflare Workers and your worker is [configured to accept TOR connections](https://support.cloudflare.com/hc/en-us/articles/203306930-Understanding-Cloudflare-Tor-support-and-Onion-Routing), this may also be `T1`, indicating a request that originated over TOR. | ||
* | ||
* If Cloudflare is unable to determine where the request originated this property is omitted. | ||
* | ||
* @example 'GB' | ||
*/ | ||
get country(): IncomingRequestCfProperties['country'] { | ||
const country = (this.#c.req.raw as CloudflareRequest).cf?.country | ||
|
||
if (!country && this.#c.__app.proxy === 'cloudflare') { | ||
return this.#c.req | ||
.headers['cf-ipcountry'] as IncomingRequestCfProperties['country'] | ||
} | ||
|
||
return country | ||
} | ||
|
||
/** | ||
* A two-letter code indicating the continent the request originated from. | ||
* | ||
* @example 'NA' | ||
*/ | ||
get continent(): IncomingRequestCfProperties['continent'] { | ||
const continent = (this.#c.req.raw as CloudflareRequest).cf?.continent | ||
|
||
if (!continent && this.#c.__app.proxy === 'cloudflare') { | ||
return this.#c.req | ||
.headers['cf-ipcontinent'] as IncomingRequestCfProperties['continent'] | ||
} | ||
|
||
return continent | ||
} | ||
|
||
/** | ||
* If known, the ISO 3166-2 code for the first-level region associated with the IP address of the incoming request. | ||
* | ||
* @example 'TX' | ||
*/ | ||
get regionCode(): IncomingRequestCfProperties['regionCode'] { | ||
return (this.#c.req.raw as CloudflareRequest).cf?.regionCode | ||
} | ||
|
||
/** | ||
* Latitude of the incoming request. | ||
* | ||
* @example '30.27130' | ||
*/ | ||
get latitude(): IncomingRequestCfProperties['latitude'] { | ||
const latitude = (this.#c.req.raw as CloudflareRequest).cf?.latitude | ||
|
||
if (!latitude && this.#c.__app.proxy === 'cloudflare') { | ||
return this.#c.req.headers['cf-iplatitude'] | ||
} | ||
|
||
return latitude | ||
} | ||
|
||
/** | ||
* Longitude of the incoming request. | ||
* | ||
* @example '-97.74260' | ||
*/ | ||
get longitude(): IncomingRequestCfProperties['longitude'] { | ||
const longitude = (this.#c.req.raw as CloudflareRequest).cf?.longitude | ||
|
||
if (!longitude && this.#c.__app.proxy === 'cloudflare') { | ||
return this.#c.req.headers['cf-iplongitude'] | ||
} | ||
|
||
return longitude | ||
} | ||
|
||
/** | ||
* Postal code of the incoming request. | ||
* | ||
* @example '78701' | ||
*/ | ||
get postalCode(): IncomingRequestCfProperties['postalCode'] { | ||
return (this.#c.req.raw as CloudflareRequest).cf?.postalCode | ||
} | ||
|
||
/** | ||
* Timezone of the incoming request. | ||
* | ||
* @example 'America/Chicago' | ||
*/ | ||
get timezone(): IncomingRequestCfProperties['timezone'] { | ||
return (this.#c.req.raw as CloudflareRequest).cf?.timezone | ||
} | ||
|
||
/** | ||
* The three-letter [IATA](https://en.wikipedia.org/wiki/IATA_airport_code) airport code of the data center that the request hit. | ||
* | ||
* @example 'DFW' | ||
*/ | ||
get datacenter(): IncomingRequestCfProperties['colo'] { | ||
return (this.#c.req.raw as CloudflareRequest).cf?.colo | ||
} | ||
} |
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
Oops, something went wrong.