@shopify/shopify-app-session-storage-redis
Version:
Shopify App Session Storage for Redis
127 lines (123 loc) • 4.93 kB
JavaScript
'use strict';
var shopifyApi = require('@shopify/shopify-api');
var migrations = require('./migrations.js');
var redisConnection = require('./redis-connection.js');
var redisMigrator = require('./redis-migrator.js');
/* eslint-disable @shopify/typescript/prefer-pascal-case-enums */
var ShopifyStorageOption;
(function (ShopifyStorageOption) {
ShopifyStorageOption["sessionKeyPrefix"] = "sessionKeyPrefix";
ShopifyStorageOption["migratorOptions"] = "migratorOptions";
ShopifyStorageOption["onError"] = "onError";
})(ShopifyStorageOption || (ShopifyStorageOption = {}));
const defaultRedisSessionStorageOptions = {
sessionKeyPrefix: 'shopify_sessions',
migratorOptions: {
migrationDBIdentifier: 'migrations',
},
};
class RedisSessionStorage {
static withCredentials(host, db, username, password, opts) {
return new RedisSessionStorage(new URL(`redis://${encodeURIComponent(username)}:${encodeURIComponent(password)}@${host}/${db}`), opts);
}
ready;
internalInit;
options;
client;
migrator;
constructor(urlOrClient, opts = {}) {
const allowedClientKeys = Object.keys(ShopifyStorageOption);
const disallowedClientKeys = Object.keys(opts).filter((key) => !allowedClientKeys.includes(key));
if (typeof urlOrClient !== 'string' &&
!(urlOrClient instanceof URL) &&
disallowedClientKeys.length > 0) {
throw new Error('Passing a RedisClient instance is not supported with options. Set the options when creating the client ' +
'instead.');
}
this.options = { ...defaultRedisSessionStorageOptions, ...opts };
this.internalInit = this.init(urlOrClient);
this.migrator = new redisMigrator.RedisSessionStorageMigrator(this.client, this.options.migratorOptions, migrations.migrationList);
this.ready = this.migrator.applyMigrations(this.internalInit);
}
async storeSession(session) {
await this.ready;
await this.client.set(session.id, JSON.stringify(session.toPropertyArray(true)));
await this.addKeyToShopList(session);
return true;
}
async loadSession(id) {
await this.ready;
let rawResult = await this.client.get(id);
if (!rawResult)
return undefined;
rawResult = JSON.parse(rawResult);
return shopifyApi.Session.fromPropertyArray(rawResult, true);
}
async deleteSession(id) {
await this.ready;
const session = await this.loadSession(id);
if (session) {
await this.removeKeyFromShopList(session.shop, id);
await this.client.del(id);
}
return true;
}
async deleteSessions(ids) {
await this.ready;
await Promise.all(ids.map((id) => this.deleteSession(id)));
return true;
}
async findSessionsByShop(shop) {
await this.ready;
const idKeysArrayString = await this.client.get(shop);
if (!idKeysArrayString)
return [];
const idKeysArray = JSON.parse(idKeysArrayString);
const results = [];
for (const idKey of idKeysArray) {
const rawResult = await this.client.get(idKey, false);
if (!rawResult)
continue;
const session = shopifyApi.Session.fromPropertyArray(JSON.parse(rawResult), true);
results.push(session);
}
return results;
}
async disconnect() {
await this.client.disconnect();
}
async addKeyToShopList(session) {
const shopKey = session.shop;
const idKey = this.client.generateFullKey(session.id);
const idKeysArrayString = await this.client.get(shopKey);
if (idKeysArrayString) {
const idKeysArray = JSON.parse(idKeysArrayString);
if (!idKeysArray.includes(idKey)) {
idKeysArray.push(idKey);
await this.client.set(shopKey, JSON.stringify(idKeysArray));
}
}
else {
await this.client.set(shopKey, JSON.stringify([idKey]));
}
}
async removeKeyFromShopList(shop, id) {
const shopKey = shop;
const idKey = this.client.generateFullKey(id);
const idKeysArrayString = await this.client.get(shopKey);
if (idKeysArrayString) {
const idKeysArray = JSON.parse(idKeysArrayString);
const index = idKeysArray.indexOf(idKey);
if (index > -1) {
idKeysArray.splice(index, 1);
await this.client.set(shopKey, JSON.stringify(idKeysArray));
}
}
}
async init(urlOrClient) {
this.client = new redisConnection.RedisConnection(urlOrClient, this.options, this.options.sessionKeyPrefix);
await this.client.connect();
}
}
exports.RedisSessionStorage = RedisSessionStorage;
//# sourceMappingURL=redis.js.map