-
Notifications
You must be signed in to change notification settings - Fork 2
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
fix: added linting, added validation for grant cookie and several test
- Loading branch information
1 parent
f92b4ed
commit 65f3e09
Showing
67 changed files
with
1,224 additions
and
645 deletions.
There are no files selected for viewing
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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,9 +1,9 @@ | ||
export default { | ||
preset: 'ts-jest', | ||
testEnvironment: 'node', | ||
// testEnvironment: 'jsdom', | ||
"moduleNameMapper": { | ||
"^@src(.*)$": "<rootDir>/src$1" | ||
}, | ||
testRegex: 'src/.*\\.test\\.(js|jsx|ts|tsx)$' | ||
} | ||
preset: 'ts-jest', | ||
testEnvironment: 'node', | ||
// testEnvironment: 'jsdom', | ||
moduleNameMapper: { | ||
'^@src(.*)$': '<rootDir>/src$1', | ||
}, | ||
testRegex: 'src/.*\\.test\\.(js|jsx|ts|tsx)$', | ||
} |
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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,31 +1,34 @@ | ||
// import typescript from '@rollup/plugin-typescript'; | ||
import typescript from 'rollup-plugin-typescript2' | ||
import resolve from '@rollup/plugin-node-resolve'; | ||
import external from 'rollup-plugin-peer-deps-external'; | ||
import commonjs from '@rollup/plugin-commonjs'; | ||
import {visualizer} from 'rollup-plugin-visualizer' | ||
import summary from "rollup-plugin-summary"; | ||
import json from '@rollup/plugin-json'; | ||
import resolve from '@rollup/plugin-node-resolve' | ||
import external from 'rollup-plugin-peer-deps-external' | ||
import commonjs from '@rollup/plugin-commonjs' | ||
import { visualizer } from 'rollup-plugin-visualizer' | ||
import summary from 'rollup-plugin-summary' | ||
import json from '@rollup/plugin-json' | ||
import packageJson from './package.json' | ||
|
||
export default ({ | ||
input: `./src/index.ts`, | ||
output: [{ | ||
file: packageJson.module, | ||
format: 'esm', | ||
sourcemap: true, | ||
}, { | ||
file: packageJson.main, | ||
format: 'cjs', | ||
sourcemap: true, | ||
}], | ||
plugins: [ | ||
external(), | ||
resolve(), | ||
json(), | ||
commonjs(), | ||
typescript(), | ||
summary(), | ||
visualizer(), | ||
] | ||
}) | ||
export default { | ||
input: `./src/index.ts`, | ||
output: [ | ||
{ | ||
file: packageJson.module, | ||
format: 'esm', | ||
sourcemap: true, | ||
}, | ||
{ | ||
file: packageJson.main, | ||
format: 'cjs', | ||
sourcemap: true, | ||
}, | ||
], | ||
plugins: [ | ||
external(), | ||
resolve(), | ||
json(), | ||
commonjs(), | ||
typescript(), | ||
summary(), | ||
visualizer(), | ||
], | ||
} |
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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,3 +1,3 @@ | ||
export * from './storyblok-auth-api' | ||
export * from './session' | ||
export * from './settings' | ||
export * from './settings' |
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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,86 +1,90 @@ | ||
import {AppSessionStore} from "@src/session/app-session-store"; | ||
import {AppSession, AppSessionKeys, AppSessionQuery} from "@src/session/app-session"; | ||
import {RequestParams} from "@src/session/request-params"; | ||
import {AppParams} from "@src/storyblok-auth-api/params/app-params"; | ||
import {getSignedCookie} from "@src/utils/signed-cookie/get-signed-cookie"; | ||
import {setSignedCookie} from "@src/utils/signed-cookie/set-signed-cookie"; | ||
import { AppSessionStore } from '@src/session/app-session-store' | ||
import { | ||
AppSession, | ||
AppSessionKeys, | ||
AppSessionQuery, | ||
} from '@src/session/app-session' | ||
import { RequestParams } from '@src/session/request-params' | ||
import { AppParams } from '@src/storyblok-auth-api/params/app-params' | ||
import { getSignedCookie } from '@src/utils/signed-cookie/get-signed-cookie' | ||
import { setSignedCookie } from '@src/utils/signed-cookie/set-signed-cookie' | ||
|
||
export type AppSessionCookieStoreFactory = (staticParams: CookieParams & AppParams) => | ||
(requestParams: RequestParams) => AppSessionStore | ||
export type AppSessionCookieStoreFactory = ( | ||
staticParams: CookieParams & AppParams, | ||
) => (requestParams: RequestParams) => AppSessionStore | ||
|
||
export type CookieParams = { | ||
jwtSecret: string | ||
// The name of the cookie that will be issued by this api endpoint handler | ||
cookieName: string | ||
jwtSecret: string | ||
// The name of the cookie that will be issued by this api endpoint handler | ||
cookieName: string | ||
} | ||
|
||
const toKeys = (keys: AppSessionQuery): AppSessionKeys => { | ||
const {spaceId, userId} = keys | ||
return ({ | ||
spaceId: typeof spaceId === 'number' ? spaceId : parseInt(spaceId, 10), | ||
userId: typeof userId === 'number' ? userId : parseInt(userId, 10), | ||
}) | ||
const { spaceId, userId } = keys | ||
return { | ||
spaceId: typeof spaceId === 'number' ? spaceId : parseInt(spaceId, 10), | ||
userId: typeof userId === 'number' ? userId : parseInt(userId, 10), | ||
} | ||
} | ||
|
||
export const isAppSessionQuery = (obj: unknown): obj is AppSessionQuery => { | ||
if (!( | ||
typeof obj === 'object' && obj !== null && 'userId' in obj && 'spaceId' in obj | ||
)) { | ||
return false | ||
} | ||
const r = obj as Record<string, unknown> | ||
return ( | ||
typeof r.userId === 'string' || | ||
typeof r.userId === 'number' | ||
) && ( | ||
typeof r.spaceId === 'string' || | ||
typeof r.spaceId === 'number' | ||
if ( | ||
!( | ||
typeof obj === 'object' && | ||
obj !== null && | ||
'userId' in obj && | ||
'spaceId' in obj | ||
) | ||
) { | ||
return false | ||
} | ||
const r = obj as Record<string, unknown> | ||
return ( | ||
(typeof r.userId === 'string' || typeof r.userId === 'number') && | ||
(typeof r.spaceId === 'string' || typeof r.spaceId === 'number') | ||
) | ||
} | ||
type AppSessionCookiePayload = { | ||
sessions: AppSession[] | ||
sessions: AppSession[] | ||
} | ||
|
||
export const simpleSessionCookieStore: AppSessionCookieStoreFactory = | ||
(params) => | ||
(requestParams) => { | ||
const {cookieName, appClientId, jwtSecret} = params | ||
const {req, res} = requestParams | ||
const getCookie = getSignedCookie(jwtSecret)<AppSessionCookiePayload>(cookieName) | ||
const setCookie = setSignedCookie(jwtSecret)<AppSessionCookiePayload>(cookieName) | ||
const getSessions = () => (getCookie(req) ?? {sessions: []}).sessions | ||
return { | ||
get: async (params) => ( | ||
getSessions().find(matches({...toKeys(params), appClientId})) | ||
), | ||
getAll: async () => ( | ||
getSessions().filter(session => ( | ||
session.appClientId === appClientId | ||
)) | ||
), | ||
put: async (session) => { | ||
const filter = matches(session) | ||
const otherSessions = getSessions().filter(s => !filter(s)) | ||
const allSessions = [ | ||
...otherSessions, | ||
session, | ||
] | ||
(params) => (requestParams) => { | ||
const { cookieName, appClientId, jwtSecret } = params | ||
const { req, res } = requestParams | ||
const getCookie = | ||
getSignedCookie(jwtSecret)<AppSessionCookiePayload>(cookieName) | ||
const setCookie = | ||
setSignedCookie(jwtSecret)<AppSessionCookiePayload>(cookieName) | ||
const getSessions = () => (getCookie(req) ?? { sessions: [] }).sessions | ||
return { | ||
get: async (params) => | ||
getSessions().find(matches({ ...toKeys(params), appClientId })), | ||
getAll: async () => | ||
getSessions().filter((session) => session.appClientId === appClientId), | ||
put: async (session) => { | ||
const filter = matches(session) | ||
const otherSessions = getSessions().filter((s) => !filter(s)) | ||
const allSessions = [...otherSessions, session] | ||
|
||
setCookie({sessions: allSessions})(res) | ||
return session | ||
}, | ||
remove: async (params) => { | ||
const sessions = getSessions() | ||
const toRemove = sessions.find(matches({...toKeys(params), appClientId})) | ||
const allOther = sessions.filter(s => s !== toRemove) | ||
setCookie({sessions: allOther})(res) | ||
return toRemove | ||
} | ||
} | ||
} | ||
setCookie({ sessions: allSessions })(res) | ||
return session | ||
}, | ||
remove: async (params) => { | ||
const sessions = getSessions() | ||
const toRemove = sessions.find( | ||
matches({ ...toKeys(params), appClientId }), | ||
) | ||
const allOther = sessions.filter((s) => s !== toRemove) | ||
setCookie({ sessions: allOther })(res) | ||
return toRemove | ||
}, | ||
} | ||
} | ||
|
||
const matches = (a: AppSessionKeys & { appClientId: string }) => (b: AppSessionKeys & { appClientId: string }) => ( | ||
const matches = | ||
(a: AppSessionKeys & { appClientId: string }) => | ||
(b: AppSessionKeys & { appClientId: string }) => | ||
a.appClientId === b.appClientId && | ||
a.spaceId === b.spaceId && | ||
a.userId === b.userId | ||
) |
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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,13 +1,10 @@ | ||
import {AppSession} from "@src/session/app-session"; | ||
import { AppSession } from '@src/session/app-session' | ||
|
||
export const shouldRefresh = (session: AppSession): boolean => ( | ||
serverRefreshIn(session) < 0 | ||
) | ||
export const shouldRefresh = (session: AppSession): boolean => | ||
serverRefreshIn(session) < 0 | ||
|
||
export const serverRefreshIn = (session: AppSession): number => ( | ||
expiresIn(session) - 60 * 1000 | ||
) | ||
export const serverRefreshIn = (session: AppSession): number => | ||
expiresIn(session) - 60 * 1000 | ||
|
||
export const expiresIn = (session: AppSession): number => ( | ||
session.expiresAt - Date.now() | ||
) | ||
export const expiresIn = (session: AppSession): number => | ||
session.expiresAt - Date.now() |
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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,17 +1,13 @@ | ||
import {AppSession, AppSessionQuery} from "@src/session/app-session"; | ||
import { AppSession, AppSessionQuery } from '@src/session/app-session' | ||
|
||
export type AppSessionStore = { | ||
get: ( | ||
keys: AppSessionQuery, | ||
options?: { | ||
autoRefresh?: boolean | ||
} | ||
) => Promise<AppSession | undefined> | ||
getAll: () => Promise<AppSession[]> | ||
put: ( | ||
session: AppSession, | ||
) => Promise<AppSession | undefined> | ||
remove: ( | ||
keys: AppSessionQuery | ||
) => Promise<AppSession | undefined> | ||
} | ||
get: ( | ||
keys: AppSessionQuery, | ||
options?: { | ||
autoRefresh?: boolean | ||
}, | ||
) => Promise<AppSession | undefined> | ||
getAll: () => Promise<AppSession[]> | ||
put: (session: AppSession) => Promise<AppSession | undefined> | ||
remove: (keys: AppSessionQuery) => Promise<AppSession | undefined> | ||
} |
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
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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,22 +1,23 @@ | ||
import {refreshToken} from "@src/storyblok-auth-api/refresh-token"; | ||
import {AppSession} from "@src/session/app-session"; | ||
import {AppParams} from "@src/storyblok-auth-api/params/app-params"; | ||
import { refreshToken } from '@src/storyblok-auth-api/refresh-token' | ||
import { AppSession } from '@src/session/app-session' | ||
import { AppParams } from '@src/storyblok-auth-api/params/app-params' | ||
|
||
/** | ||
* Returns a new session that is refreshed | ||
* @return a session that is refreshed | ||
* @param params | ||
*/ | ||
export const refreshAppSession = (params: AppParams) => | ||
async (oldSession: AppSession): Promise<AppSession | undefined> => { | ||
if (!oldSession.refreshToken) { | ||
return undefined | ||
} | ||
return refreshToken(params)(oldSession.refreshToken).then( | ||
({access_token, expires_in}) => ({ | ||
...oldSession, | ||
accessToken: access_token, | ||
expiresAt: Date.now() + expires_in * 1000 | ||
}) | ||
).catch(() => undefined) | ||
} | ||
export const refreshAppSession = | ||
(params: AppParams) => | ||
async (oldSession: AppSession): Promise<AppSession | undefined> => { | ||
if (!oldSession.refreshToken) { | ||
return undefined | ||
} | ||
return refreshToken(params)(oldSession.refreshToken) | ||
.then(({ access_token, expires_in }) => ({ | ||
...oldSession, | ||
accessToken: access_token, | ||
expiresAt: Date.now() + expires_in * 1000, | ||
})) | ||
.catch(() => undefined) | ||
} |
Oops, something went wrong.