Last active
June 5, 2022 19:26
-
-
Save debuss/ef2e8738bf6d434854afcfe5f06cb734 to your computer and use it in GitHub Desktop.
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
/** | |
* CustomSessionStorage implementation with FaunaDb for your Node API Shopify app. | |
* | |
* On Fauna Dashboard, in my database, I created a Collection "Sessions" (with a TTL of 2 days, but configure it as you wish). | |
* I also added an Index "session_by_id" with Terms set as "data.id" and Serialized. | |
* | |
* In the constructor, replace my settings with yours to make the connection. | |
* If you have a different Collection and/or Index, then also update each method to use the correct configuration. | |
* | |
* @author Alexandre DEBUSSCHÈRE <alexandre@kosmonaft.dev> | |
* @see https://github.com/Shopify/shopify-node-api/blob/main/docs/usage/customsessions.md | |
* @see https://fauna.com/ | |
*/ | |
import faunadb from "faunadb"; | |
import "dotenv/config"; | |
import { Session } from "@shopify/shopify-api/dist/auth/session/index.js"; | |
const q = faunadb.query; | |
class FaunaDbStore { | |
constructor() { | |
this.client = new faunadb.Client({ | |
secret: process.env.FAUNADB_SECRET, | |
domain: "db.eu.fauna.com", | |
port: 443, | |
scheme: "https", | |
}); | |
} | |
/** | |
* @param session | |
* @returns {Promise<boolean>} | |
*/ | |
async storeCallback(session) { | |
try { | |
await this.client.query( | |
// Upsert | |
q.Let( | |
{ | |
match: q.Match(q.Index("session_by_id"), session.id), | |
data: { data: session }, | |
}, | |
q.If( | |
q.Exists(q.Var("match")), | |
q.Update(q.Select("ref", q.Get(q.Var("match"))), q.Var("data")), | |
q.Create(q.Collection("Sessions"), q.Var("data")) | |
) | |
) | |
); | |
return true; | |
} catch (err) { | |
throw new Error(err); | |
} | |
} | |
/** | |
* @param id | |
* @returns {Promise<undefined|*>} | |
*/ | |
async loadCallback(id) { | |
let reply = undefined; | |
try { | |
await this.client | |
.query(q.Get(q.Match(q.Index("session_by_id"), id))) | |
.then((response) => (reply = response.data)); | |
if (!reply) { | |
return undefined; | |
} | |
return Session.cloneSession(reply, reply.id); | |
} catch (err) { | |
throw new Error(err); | |
} | |
} | |
/** | |
* @param id | |
* @returns {Promise<boolean>} | |
*/ | |
async deleteCallback(id) { | |
try { | |
await this.client.query( | |
q.Delete(q.Select("ref", q.Get(q.Match(q.Index("session_by_id"), id)))) | |
); | |
return true; | |
} catch (err) { | |
throw new Error(err); | |
} | |
} | |
} | |
export default FaunaDbStore; |
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
// server/index.js | |
// ... | |
import faunadb from "faunadb"; | |
import FaunaDbStore from "./storage/faunadb-store.js"; | |
const sessionStorage = new FaunaDbStore(); | |
Shopify.Context.initialize({ | |
API_KEY: process.env.SHOPIFY_API_KEY, | |
API_SECRET_KEY: process.env.SHOPIFY_API_SECRET, | |
SCOPES: process.env.SCOPES.split(","), | |
HOST_NAME: process.env.HOST.replace(/https:\/\//, ""), | |
API_VERSION: ApiVersion.April22, | |
IS_EMBEDDED_APP: true, | |
// This should be replaced with your preferred storage strategy | |
SESSION_STORAGE: | |
process.env.NODE_ENV === "production" | |
? new Shopify.Session.CustomSessionStorage( | |
sessionStorage.storeCallback.bind(sessionStorage), | |
sessionStorage.loadCallback.bind(sessionStorage), | |
sessionStorage.deleteCallback.bind(sessionStorage) | |
) | |
: new Shopify.Session.MemorySessionStorage(), | |
}); |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment