Skip to content
This repository has been archived by the owner on Apr 11, 2024. It is now read-only.

Commit

Permalink
Add isActive session method
Browse files Browse the repository at this point in the history
  • Loading branch information
carmelal committed Mar 30, 2021
1 parent fa9ef02 commit 6726dca
Show file tree
Hide file tree
Showing 9 changed files with 89 additions and 16 deletions.
9 changes: 9 additions & 0 deletions src/auth/session/session.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import {OnlineAccessInfo} from '../oauth/types';
import {Context} from '../../context';

/**
* Stores App information from logged in merchants so they can make authenticated requests to the Admin API.
Expand Down Expand Up @@ -27,6 +28,14 @@ class Session {
public onlineAccessInfo?: OnlineAccessInfo;

constructor(readonly id: string) {}

public isActive(): boolean {
const scopesChanged = !Context.SCOPES.equals(this.scope);
if (!scopesChanged && this.accessToken && (!this.expires || this.expires >= new Date())) {
return true;
}
return false;
}
}

export {Session};
6 changes: 3 additions & 3 deletions src/auth/session/session_storage.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import {Session} from './session';
import {SessionInterface} from './types';

/**
* Defines the strategy to be used to store sessions for the Shopify App.
Expand All @@ -10,14 +10,14 @@ interface SessionStorage {
*
* @param session Session to store
*/
storeSession(session: Session): Promise<boolean>;
storeSession(session: SessionInterface): Promise<boolean>;

/**
* Loads a session from storage.
*
* @param id Id of the session to load
*/
loadSession(id: string): Promise<Session | undefined>;
loadSession(id: string): Promise<SessionInterface | undefined>;

/**
* Deletes a session from storage.
Expand Down
8 changes: 4 additions & 4 deletions src/auth/session/storage/memory.ts
Original file line number Diff line number Diff line change
@@ -1,15 +1,15 @@
import {Session} from '../session';
import {SessionInterface} from '../types';
import {SessionStorage} from '../session_storage';

export class MemorySessionStorage implements SessionStorage {
private sessions: { [id: string]: Session; } = {};
private sessions: { [id: string]: SessionInterface; } = {};

public async storeSession(session: Session): Promise<boolean> {
public async storeSession(session: SessionInterface): Promise<boolean> {
this.sessions[session.id] = session;
return true;
}

public async loadSession(id: string): Promise<Session | undefined> {
public async loadSession(id: string): Promise<SessionInterface | undefined> {
return this.sessions[id] || undefined;
}

Expand Down
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
import '../../../test/test_helper';
import '../../../../test/test_helper';

import {Session} from '../session';
import {CustomSessionStorage} from '../storage/custom';
import {SessionStorageError} from '../../../error';
import {Session} from '../../session';
import {CustomSessionStorage} from '../custom';
import {SessionStorageError} from '../../../../error';

describe('custom session storage', () => {
test('can perform actions', async () => {
Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import '../../../test/test_helper';
import '../../../../test/test_helper';

import {Session} from '../session';
import {MemorySessionStorage} from '../storage/memory';
import {Session} from '../../session';
import {MemorySessionStorage} from '../memory';

test('can store and delete sessions in memory', async () => {
const sessionId = 'test_session';
Expand Down
50 changes: 50 additions & 0 deletions src/auth/session/test/session.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
import {ApiVersion, ContextParams} from '../../../base_types';
import {Context} from '../../../context';
import '../../../test/test_helper';
import {Session} from '..';

const validContextParams: ContextParams = {
API_KEY: 'C_major',
API_SECRET_KEY: 'A_minor',
SCOPES: ['ice_scream_scope', 'news_scope'],
HOST_NAME: 'chopin',
API_VERSION: ApiVersion.Unstable,
IS_EMBEDDED_APP: true,
IS_PRIVATE_APP: false,
LOG_FILE: 'going-chopin-with-chopin.txt',
};

describe('session', () => {
it('can clone a session', () => {
const session = new Session('original');
const sessionClone = Session.cloneSession(session, 'new');

expect(session.id).not.toEqual(sessionClone.id);
expect(session.shop).toStrictEqual(sessionClone.shop);
expect(session.state).toStrictEqual(sessionClone.state);
expect(session.scope).toStrictEqual(sessionClone.scope);
expect(session.expires).toStrictEqual(sessionClone.expires);
expect(session.isOnline).toStrictEqual(sessionClone.isOnline);
expect(session.accessToken).toStrictEqual(sessionClone.accessToken);
expect(session.onlineAccessInfo).toStrictEqual(sessionClone.onlineAccessInfo);
});
});

describe('isActive', () => {
it('returns true if session is active', () => {
Context.initialize(validContextParams);
const session = new Session('active');
session.scope = 'ice_cream_scope,news_scope';
session.accessToken = 'indeed';
session.expires = new Date(Date.now() + 86400);
expect(session.isActive()).toBe(true);
});

it('returns false if session is not active', () => {
Context.initialize(validContextParams);
const session = new Session('not_active');
session.scope = 'not_same';
session.expires = new Date(Date.now() - 1);
expect(session.isActive()).toBe(false);
});
});
13 changes: 13 additions & 0 deletions src/auth/session/types.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
import {OnlineAccessInfo} from '../oauth/types';

export interface SessionInterface {
readonly id: string;
shop: string;
state: string;
scope: string;
expires?: Date;
isOnline?: boolean;
accessToken?: string;
onlineAccessInfo?: OnlineAccessInfo;
isActive(): boolean;
}
2 changes: 1 addition & 1 deletion src/base_types.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import {SessionStorage} from './auth/session';
import {AuthScopes} from './auth/scopes';
import {SessionStorage} from './auth/session/session_storage';

export interface ContextParams {
API_KEY: string;
Expand Down
3 changes: 2 additions & 1 deletion src/context.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import * as ShopifyErrors from './error';
import {SessionStorage, MemorySessionStorage} from './auth/session';
import {SessionStorage} from './auth/session/session_storage';
import {MemorySessionStorage} from './auth/session/storage/memory';
import {ApiVersion, ContextParams} from './base_types';
import {AuthScopes} from './auth/scopes';

Expand Down

0 comments on commit 6726dca

Please sign in to comment.