Skip to content

Instantly share code, notes, and snippets.

@espeon
Last active June 8, 2020 02:24
Show Gist options
  • Select an option

  • Save espeon/96d419bffda55e79b4959428e05c0e70 to your computer and use it in GitHub Desktop.

Select an option

Save espeon/96d419bffda55e79b4959428e05c0e70 to your computer and use it in GitHub Desktop.
import {
createConnection,
getConnection,
getManager,
EntitySchema
} from "typeorm";
import Models from "./models";
const Adapter = (options = {}) => {
// Load models / schemas (check for custom models / schemas first)
const Account = Models.Account.model;
const AccountSchema = Models.Account.schema;
const User = Models.User.model;
const UserSchema = Models.User.schema;
const Session = Models.Session.model;
const SessionSchema = Models.Session.schema;
const VerificationRequest = Models.VerificationRequest.model;
const VerificationRequestSchema = Models.VerificationRequest.schema;
// Models default to being suitable for ANSI SQL database
// Some flexiblity is required to support non-SQL databases
let idKey = "id";
// Parse config (uses options)
const config = {
name: "maki-postgres",
autoLoadEntities: true,
entities: [
new EntitySchema(AccountSchema),
new EntitySchema(UserSchema),
new EntitySchema(SessionSchema),
new EntitySchema(VerificationRequestSchema)
],
logging: false,
type: "postgres",
host: "192.168.1.1",
port: 5432,
username: "pgadmin",
password: "p155w3rd",
database: "postgres",
synchronize: true,
entityPrefix: "nextauth_"
};
let connection = null;
async function getAdapter(appOptions) {
// Helper function to reuse / restablish connections
// (useful if they drop when after being idle)
async function _connect() {
// Get current connection by name
connection = getConnection(config.name);
// If connection is no longer established, reconnect
if (!connection.isConnected) {
connection = await connection.connect();
console.log("reconnected to postgres");
}
}
if (!connection) {
// If no connection, create new connection
try {
connection = await createConnection(config);
console.log("connected to postgres");
} catch (error) {
if (error.name === "AlreadyHasActiveConnectionError") {
// If creating connection fails because it's already
// been re-established, check it's really up
await _connect();
} else {
console.error("ADAPTER_CONNECTION_ERROR", error);
}
}
} else {
// If the connection object already exists, ensure it's valid
await _connect();
}
async function getAccessToken(accessToken) {
try {
console.log(connection.isConnected)
const session = await connection
.getRepository(Session)
.findOne({ where: { userId: 2 } });
console.log(session)
// Check session has not expired (do not return it if it has)
if (
session &&
session.sessionExpires &&
new Date() > new Date(session.sessionExpires)
) {
// @TODO Delete old sessions from database
return null;
}
return session;
} catch (error) {
console.error("GET_SESSION_ERROR", error);
return Promise.reject(new Error("GET_SESSION_ERROR", error));
}
}
async function getAuthToken(userId) {
try {
const cool = await connection
.getRepository(Account)
.findOne({ where: { userId: userId } });
if (
cool.accessTokenExpires == null ||
Date.parse(cool.accessTokenExpires) < Date.now()
) {
let data = {
client_id: process.env.DISCORD_ID,
client_secret: process.env.DISCORD_SECRET,
grant_type: "refresh_token",
refresh_token: cool.refreshToken,
redirect_uri: process.env.SITE || "https://maki-site.glitch.me",
scope: "email guilds identify"
};
postData("https://discord.com/api/oauth2/token", data).then(
async data => {
if (data.error) return;
cool.refreshToken = data.refresh_token;
cool.accessToken = data.access_token;
cool.accessTokenExpires = new Date(
Date.now() + data.expires_in
).toISOString();
await connection.getRepository(Account).save(cool);
return cool.accessToken;
}
);
}
return cool.accessToken;
} catch (error) {
console.error("GET_SESSION_ERROR", error);
return Promise.reject(new Error("GET_SESSION_ERROR", error));
}
}
return Promise.resolve({
getAccessToken,
getAuthToken
});
}
return {
getAdapter
};
};
export default {
Adapter,
Models
};
async function postData(url = "", data = {}) {
// Default options are marked with *
const response = await fetch(url, {
method: "POST", // *GET, POST, PUT, DELETE, etc.
mode: "cors", // no-cors, *cors, same-origin
cache: "no-cache", // *default, no-cache, reload, force-cache, only-if-cached
credentials: "same-origin", // include, *same-origin, omit
headers: {
"Content-Type": "application/x-www-form-urlencoded"
},
redirect: "follow", // manual, *follow, error
referrerPolicy: "no-referrer", // no-referrer, *no-referrer-when-downgrade, origin, origin-when-cross-origin, same-origin, strict-origin, strict-origin-when-cross-origin, unsafe-url
body: serialize(data) // body data type must match "Content-Type" header
});
return response.json(); // parses JSON response into native JavaScript objects
}
const serialize = function(obj) {
var str = [];
for (var p in obj)
if (obj.hasOwnProperty(p)) {
str.push(encodeURIComponent(p) + "=" + encodeURIComponent(obj[p]));
}
return str.join("&");
};
import db from "../../src/typeorm.js";
export default async (req, res) => {
let token = req.headers.authorization.replace("Bearer ", "")
const {
getAccessToken,
getAuthToken
} = await db.Adapter().getAdapter();
let accessToken = await getAccessToken(token);
console.log(token, accessToken)
if(!accessToken) return res.send(500,"")
let authToken = await getAuthToken(accessToken.userId);
let url = "https://discord.com/api/v6/users/@me";
let data = {
method: "GET",
headers: {
Authorization: `Bearer ${authToken}`
},
credentials: "same-origin"
};
return fetch(url, data)
.then(res => res.json())
.then(json => res.send(json));
};
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment