88 lines
3.3 KiB
TypeScript
88 lines
3.3 KiB
TypeScript
import DiscordOauth2 from 'discord-oauth2';
|
|
import {User} from "../models/User";
|
|
import {redisClient} from "../app";
|
|
|
|
const oauth = new DiscordOauth2();
|
|
|
|
/**
|
|
* Retrieves an access & refresh token from the discord api
|
|
* @param code The authorization code from the callback
|
|
*/
|
|
export const createTokenByCode = (code: string) => oauth.tokenRequest({
|
|
grantType: "authorization_code",
|
|
scope: "identify guilds",
|
|
clientId: process.env.DC_CLIENT,
|
|
clientSecret: process.env.DC_SECRET,
|
|
redirectUri: process.env.DC_REDIRECT_URI,
|
|
code
|
|
});
|
|
|
|
/**
|
|
* Generate a new access token from the refresh token
|
|
* @param refreshToken The token to refresh the access token
|
|
*/
|
|
export const generateToken = (refreshToken: string) => oauth.tokenRequest({
|
|
grantType: "refresh_token",
|
|
scope: "identify guilds",
|
|
clientId: process.env.DC_CLIENT,
|
|
clientSecret: process.env.DC_SECRET,
|
|
redirectUri: process.env.DC_REDIRECT_URI,
|
|
refreshToken
|
|
});
|
|
|
|
/**
|
|
* Updates a user's access token if it is expired
|
|
* @param refreshDate The date of when to renew the provided access token
|
|
* @param refreshToken The token to refresh the access token
|
|
* @param accessToken The token to access the discord api
|
|
*/
|
|
export const updateToken = async (refreshDate: Date, refreshToken: string, accessToken: string) => {
|
|
let token = accessToken;
|
|
if (refreshDate.valueOf() < Date.now()) {
|
|
const newToken = await generateToken(refreshToken);
|
|
token = newToken.access_token;
|
|
User.update({
|
|
accessToken: token, refreshDate: new Date(Date.now() + newToken.expires_in),
|
|
refreshToken: newToken.refresh_token
|
|
}, {where: {refreshToken: refreshToken}});
|
|
}
|
|
|
|
return token;
|
|
}
|
|
|
|
/**
|
|
* Gets the guilds from the access token.
|
|
* This function also automatically renews the access token if it expires
|
|
* @param refreshDate The date of when to renew the provided access token
|
|
* @param refreshToken The token to refresh the access token
|
|
* @param accessToken The token to access the discord api
|
|
*/
|
|
export const getGuilds = async (refreshDate: Date, refreshToken: string, accessToken: string) => {
|
|
const cacheResults = await redisClient.get(`guilds:${accessToken}`);
|
|
|
|
if (cacheResults) {
|
|
return JSON.parse(cacheResults) as DiscordOauth2.PartialGuild[];
|
|
} else {
|
|
const guilds = await oauth.getUserGuilds(await updateToken(refreshDate, refreshToken, accessToken));
|
|
await redisClient.setEx(`guilds:${accessToken}`, 60 * 60 * 24, JSON.stringify(guilds));
|
|
return guilds;
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Checks if the user is the owner of the guild or has the manage server permission
|
|
* @param refreshDate The date of when to renew the provided access token
|
|
* @param refreshToken The token to refresh the access token
|
|
* @param accessToken The token to access the discord api
|
|
* @param guildId The id of the guild
|
|
*/
|
|
export const canEditGuild = async (refreshDate: Date, refreshToken: string, accessToken: string, guildId: string) => {
|
|
const guilds = await getGuilds(refreshDate, refreshToken, accessToken);
|
|
return guilds.some(guild => guild.id === guildId && (guild.owner || (guild.permissions && (guild.permissions & 0x8))));
|
|
}
|
|
|
|
/**
|
|
* Gets user information from the discord api
|
|
* @param token The access token of the user
|
|
*/
|
|
export const getUser = (token: string) => oauth.getUser(token); |