diff --git a/src/auth.ts b/src/auth.ts index 9d08d9c..fffbc76 100644 --- a/src/auth.ts +++ b/src/auth.ts @@ -3,6 +3,7 @@ import type { EndpointOutput } from "@sveltejs/kit/types/endpoint"; import { RequestEvent } from "@sveltejs/kit/types/hooks"; import cookie from "cookie"; import { JWTPayload, jwtVerify, KeyLike, SignJWT } from "jose"; +import { base64Encode } from "./helpers"; import type { JWT, Session } from "./interfaces"; import { join } from "./path"; import type { Provider } from "./providers"; @@ -40,7 +41,7 @@ export class Auth { if (this.config?.providers?.length) { const provs = this.config?.providers?.map((provider) => provider.id).join("+"); - return encoder.encode(provs); + return encoder.encode(base64Encode(provs)); } return encoder.encode("svelte_auth_secret"); diff --git a/src/helpers.ts b/src/helpers.ts index 776ab63..73268f2 100644 --- a/src/helpers.ts +++ b/src/helpers.ts @@ -1,3 +1,17 @@ export function ucFirst(val: string) { return val.charAt(0).toUpperCase() + val.slice(1); } + +export function base64Encode(str: string): string { + if (typeof btoa === 'undefined') { + return Buffer.from(str).toString('base64'); + } + return btoa(str); +} + +export function base64Decode(str: string): string { + if (typeof atob === 'undefined') { + return Buffer.from(str, 'base64').toString(); + } + return atob(str); +} diff --git a/src/providers/oauth2.base.ts b/src/providers/oauth2.base.ts index 41f6c5f..eab0cd8 100644 --- a/src/providers/oauth2.base.ts +++ b/src/providers/oauth2.base.ts @@ -1,5 +1,6 @@ import type { EndpointOutput } from "@sveltejs/kit/types/endpoint"; import { RequestEvent } from "@sveltejs/kit/types/hooks"; +import { base64Encode, base64Decode } from "../helpers"; import type { Auth } from "../auth"; import type { CallbackResult } from "../types"; import { Provider, ProviderConfig } from "./base"; @@ -39,7 +40,7 @@ export abstract class OAuth2BaseProvider< const state = [ `redirect=${url.searchParams.get("redirect") ?? this.getUri(auth, "/", url.host)}`, ].join(","); - const base64State = Buffer.from(state).toString("base64"); + const base64State = base64Encode(state); const nonce = Math.round(Math.random() * 1000).toString(); // TODO: Generate random based on user values const authUrl = await this.getAuthorizationUrl(event, auth, base64State, nonce); @@ -61,7 +62,7 @@ export abstract class OAuth2BaseProvider< getStateValue(query: URLSearchParams, name: string) { if (query.get("state")) { - const state = Buffer.from(query.get("state")!, "base64").toString(); + const state = base64Decode(query.get("state")!); return state .split(",") .find((state) => state.startsWith(`${name}=`)) diff --git a/src/providers/reddit.ts b/src/providers/reddit.ts index 1ebf8ff..11fccd2 100644 --- a/src/providers/reddit.ts +++ b/src/providers/reddit.ts @@ -1,3 +1,4 @@ +import { base64Encode } from "../helpers"; import { OAuth2Provider, OAuth2ProviderConfig } from "./oauth2"; export interface RedditProfile { @@ -228,7 +229,7 @@ export class RedditOAuth2Provider extends OAuth2Provider< headers: { ...config.headers, Authorization: - "Basic " + Buffer.from(`${config.apiKey}:${config.apiSecret}`).toString("base64"), + "Basic " + base64Encode(`${config.apiKey}:${config.apiSecret}`), }, authorizationParams: { ...config.authorizationParams,