mirror of
https://github.com/Dan6erbond/sk-auth.git
synced 2025-04-09 01:16:54 +02:00
* 🎉 Scaffold example app with SvelteKit barebones skeleton * 💄 Add TWCSS and base styles with fonts Inter/Fira Mono * 🔧 Add `exports` and `types` to `package.json` and update `tsconfig.json` for Vite-compatible build output * ➕ Add local dependency to `svelte-kit-auth` as symlink * 🔧 Update example app env variables * ✨ Add basic auth config to example app * ♻️ Export all providers from `/providers` module * 🎨 Make `Auth` class default export of lib * 🚚 Rename `example-app` to `app` * ➕ Use `file:` instead of `link:` for local dependency to `svelte-kit-auth` * 🔧 Add `JWT_SECRET_KEY` to env and config * 🎨 Add `RedditOAuthProvider.profileHandler` for general use and stripping of payload * ✨ Export auth API routes from app * ⬆️ Update local deps * ✨ Add `host` and `basePath` to general config and improve recognition of routes * 🚨 Exclude `app` from TS build * 📌 Undo `file:` mapping dependency for usage with Vite TODO: Needs to be fixed for release. * 🎨 Enable TS `strict` mode and set target to `es2017` * 📌 Undo `file:` mapping dependency for usage with Vite * 🚨 Format and lint files * 🍱 Add logo * ✨ Add login and profile routes to example app for showcase and testing * 💄 Add PrismJS and create homepage with example * 🔨 Add `build:watch`
124 lines
2.7 KiB
TypeScript
124 lines
2.7 KiB
TypeScript
import type { ServerRequest } from "@sveltejs/kit/types/endpoint";
|
|
import { OAuth2Provider, OAuth2ProviderConfig } from "./oauth2";
|
|
|
|
interface RedditOAuthProviderConfig extends OAuth2ProviderConfig {
|
|
apiKey: string;
|
|
apiSecret: string;
|
|
scope?: string;
|
|
duration?: "temporary" | "permanent";
|
|
}
|
|
|
|
const redditProfileHandler = ({
|
|
is_employee,
|
|
has_external_account,
|
|
snoovatar_img,
|
|
verified,
|
|
id,
|
|
over_18,
|
|
is_gold,
|
|
is_mod,
|
|
awarder_karma,
|
|
has_verified_email,
|
|
is_suspended,
|
|
icon_img,
|
|
pref_nightmode,
|
|
awardee_karma,
|
|
password_set,
|
|
link_karma,
|
|
total_karma,
|
|
name,
|
|
created,
|
|
created_utc,
|
|
comment_karma,
|
|
}) => ({
|
|
is_employee,
|
|
has_external_account,
|
|
snoovatar_img,
|
|
verified,
|
|
id,
|
|
over_18,
|
|
is_gold,
|
|
is_mod,
|
|
awarder_karma,
|
|
has_verified_email,
|
|
is_suspended,
|
|
icon_img,
|
|
pref_nightmode,
|
|
awardee_karma,
|
|
password_set,
|
|
link_karma,
|
|
total_karma,
|
|
name,
|
|
created,
|
|
created_utc,
|
|
comment_karma,
|
|
});
|
|
|
|
const defaultConfig: Partial<RedditOAuthProviderConfig> = {
|
|
id: "reddit",
|
|
scope: "identity",
|
|
duration: "temporary",
|
|
profile: redditProfileHandler,
|
|
};
|
|
|
|
export class RedditOAuthProvider extends OAuth2Provider<RedditOAuthProviderConfig> {
|
|
constructor(config: RedditOAuthProviderConfig) {
|
|
super({
|
|
...defaultConfig,
|
|
...config,
|
|
});
|
|
}
|
|
|
|
static profileHandler = redditProfileHandler;
|
|
|
|
async getSigninUrl({ host }: ServerRequest, state: string) {
|
|
const endpoint = "https://www.reddit.com/api/v1/authorize";
|
|
|
|
const data = {
|
|
client_id: this.config.apiKey,
|
|
response_type: "code",
|
|
state,
|
|
redirect_uri: this.getCallbackUri(host),
|
|
duration: this.config.duration!,
|
|
scope: this.config.scope!,
|
|
};
|
|
|
|
const url = `${endpoint}?${new URLSearchParams(data)}`;
|
|
return url;
|
|
}
|
|
|
|
async getTokens(code: string, redirectUri: string) {
|
|
const endpoint = "https://www.reddit.com/api/v1/access_token";
|
|
|
|
const data = {
|
|
code,
|
|
redirect_uri: redirectUri,
|
|
grant_type: "authorization_code",
|
|
};
|
|
const body = Object.entries(data)
|
|
.map(([key, value]) => `${encodeURIComponent(key)}=${encodeURIComponent(value)}`)
|
|
.join("&");
|
|
|
|
const res = await fetch(endpoint, {
|
|
method: "POST",
|
|
headers: {
|
|
"Content-Type": "application/x-www-form-urlencoded",
|
|
Authorization:
|
|
"Basic " +
|
|
Buffer.from(`${this.config.apiKey}:${this.config.apiSecret}`).toString("base64"),
|
|
},
|
|
body,
|
|
});
|
|
|
|
return await res.json();
|
|
}
|
|
|
|
async getUserProfile(tokens: any) {
|
|
const endpoint = "https://oauth.reddit.com/api/v1/me";
|
|
const res = await fetch(endpoint, {
|
|
headers: { Authorization: `${tokens.token_type} ${tokens.access_token}` },
|
|
});
|
|
return await res.json();
|
|
}
|
|
}
|