mirror of
https://github.com/janishutz/oidc-login-sdk.git
synced 2026-10-08 17:36:20 +02:00
feat: basic sdks
This commit is contained in:
1 parent
4d7b326df5
commit
9652003018
11 files changed
+3866
-12
No files matched your search
Whitespace-only changes.
Executable
+7
@@ -0,0 +1,7 @@
|
|||||||
|
#!/bin/bash
|
||||||
|
|
||||||
|
tsc --declaration
|
||||||
|
cp ./package.json ./dist
|
||||||
|
cp ./README.md ./dist
|
||||||
|
|
||||||
|
echo "Done"
|
||||||
@@ -1,5 +1,5 @@
|
|||||||
{
|
{
|
||||||
"name": "@janishutz/oidc-login-browser",
|
"name": "@janishutz/oidc-login-sdk-browser",
|
||||||
"version": "1.0.0",
|
"version": "1.0.0",
|
||||||
"description": "SDK to communicate with and log into a backend running express-openid-connect",
|
"description": "SDK to communicate with and log into a backend running express-openid-connect",
|
||||||
"homepage": "https://github.com/janishutz/oidc-login-sdk-browser#readme",
|
"homepage": "https://github.com/janishutz/oidc-login-sdk-browser#readme",
|
||||||
|
|||||||
+36
-3
@@ -1,8 +1,41 @@
|
|||||||
|
import request, {
|
||||||
|
AuthError
|
||||||
|
} from './request.js';
|
||||||
|
import config from './config.js';
|
||||||
|
|
||||||
export const login = () => {
|
export const login = () => {
|
||||||
sessionStorage.setItem( 'redirect', location.pathname );
|
sessionStorage.setItem( 'redirect', location.pathname );
|
||||||
location.href = '/login';
|
location.href = config.get().loginEndpoint ?? '/auth/v2/login';
|
||||||
};
|
};
|
||||||
|
|
||||||
export const check = () => {};
|
export const check = async () => {
|
||||||
|
let status: boolean;
|
||||||
|
|
||||||
export const logout = () => {};
|
try {
|
||||||
|
status = ( await request.get( config.get().authCheckEndpoint ?? '/auth/v2/check' ) ).ok;
|
||||||
|
} catch ( e ) {
|
||||||
|
if ( e instanceof AuthError ) {
|
||||||
|
status = false;
|
||||||
|
} else {
|
||||||
|
throw e;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if ( !status && config.get().checkAutoRedirect ) {
|
||||||
|
location.href = getRedirect();
|
||||||
|
}
|
||||||
|
|
||||||
|
return status;
|
||||||
|
};
|
||||||
|
|
||||||
|
export const getRedirect = (): string | null => {
|
||||||
|
const item = sessionStorage.getItem( 'redirect' );
|
||||||
|
|
||||||
|
sessionStorage.removeItem( 'redirect' );
|
||||||
|
|
||||||
|
return item;
|
||||||
|
};
|
||||||
|
|
||||||
|
export const logout = async () => {
|
||||||
|
location.href = config.get().logoutEndpoint ?? '/auth/v2/logout';
|
||||||
|
};
|
||||||
Vendored
+2
-1
@@ -5,8 +5,9 @@ export interface Config {
|
|||||||
'defaultAuthErrorResolution': AuthErrorResolution;
|
'defaultAuthErrorResolution': AuthErrorResolution;
|
||||||
'authErrorEvent'?: string;
|
'authErrorEvent'?: string;
|
||||||
'authCheckEndpoint'?: string;
|
'authCheckEndpoint'?: string;
|
||||||
'loginEndpoing'?: string;
|
'loginEndpoint'?: string;
|
||||||
'logoutEndpoint'?: string;
|
'logoutEndpoint'?: string;
|
||||||
|
'checkAutoRedirect'?: boolean;
|
||||||
}
|
}
|
||||||
|
|
||||||
declare global {
|
declare global {
|
||||||
|
|||||||
@@ -1,3 +1,6 @@
|
|||||||
|
import {
|
||||||
|
AuthErrorResolution
|
||||||
|
} from './dtype.js';
|
||||||
import config from './config.js';
|
import config from './config.js';
|
||||||
import {
|
import {
|
||||||
login
|
login
|
||||||
@@ -8,13 +11,13 @@ export class AuthError extends Error {}
|
|||||||
export class UnownedError extends Error {}
|
export class UnownedError extends Error {}
|
||||||
|
|
||||||
|
|
||||||
const get = async ( url: string ): Promise<Response> => {
|
const get = async ( url: string, authErrorResolution?: AuthErrorResolution ): Promise<Response> => {
|
||||||
return await wrapper( url, {
|
return await wrapper( url, {
|
||||||
'credentials': 'include'
|
'credentials': 'include'
|
||||||
} );
|
}, authErrorResolution );
|
||||||
};
|
};
|
||||||
|
|
||||||
const post = async ( url: string, payload: string, mime: string = 'application/json' ): Promise<Response> => {
|
const post = async ( url: string, payload: string, mime: string = 'application/json', authErrorResolution?: AuthErrorResolution ): Promise<Response> => {
|
||||||
return await wrapper( url, {
|
return await wrapper( url, {
|
||||||
'credentials': 'include',
|
'credentials': 'include',
|
||||||
'body': payload,
|
'body': payload,
|
||||||
@@ -22,10 +25,10 @@ const post = async ( url: string, payload: string, mime: string = 'application/j
|
|||||||
'headers': {
|
'headers': {
|
||||||
'Content-Type': mime ?? 'application/json'
|
'Content-Type': mime ?? 'application/json'
|
||||||
}
|
}
|
||||||
} );
|
}, authErrorResolution );
|
||||||
};
|
};
|
||||||
|
|
||||||
const wrapper = async ( url: string, opts: RequestInit ): Promise<Response> => {
|
const wrapper = async ( url: string, opts: RequestInit, authErrorResolution?: AuthErrorResolution ): Promise<Response> => {
|
||||||
const res = await fetch( config.get().backendURL + url, {
|
const res = await fetch( config.get().backendURL + url, {
|
||||||
'redirect': 'manual',
|
'redirect': 'manual',
|
||||||
...opts
|
...opts
|
||||||
@@ -36,7 +39,7 @@ const wrapper = async ( url: string, opts: RequestInit ): Promise<Response> => {
|
|||||||
document.dispatchEvent( new CustomEvent( 'autherror' ) );
|
document.dispatchEvent( new CustomEvent( 'autherror' ) );
|
||||||
}
|
}
|
||||||
|
|
||||||
if ( config.get().defaultAuthErrorResolution === 'resolve' ) {
|
if ( ( authErrorResolution && authErrorResolution === 'resolve' ) || ( !authErrorResolution && config.get().defaultAuthErrorResolution === 'resolve' ) ) {
|
||||||
login();
|
login();
|
||||||
} else {
|
} else {
|
||||||
throw new AuthError( 'ERR_USER_UNAUTHORIZED' );
|
throw new AuthError( 'ERR_USER_UNAUTHORIZED' );
|
||||||
|
|||||||
@@ -0,0 +1,15 @@
|
|||||||
|
# janishutz/oidc-login-sdk-server
|
||||||
|
This SDK is designed to run together with my browser sdk.
|
||||||
|
It is a simple wrapper of `express-openid-connect`.
|
||||||
|
|
||||||
|
It is highly recommended that you use a proper session store (such as the redis store from express-session) to store the sessions.
|
||||||
|
|
||||||
|
## Usage
|
||||||
|
Make sure that you have the following environment variables set
|
||||||
|
```env
|
||||||
|
OIDC_CLIENT_ID=<CLIENT ID>
|
||||||
|
OIDC_CLIENT_SECRET=<CLIENT SECRET>
|
||||||
|
SIGNING_SECRET=<LONG RANDOM STRING FOR COOKIE SIGNING>
|
||||||
|
```
|
||||||
|
|
||||||
|
**More details to come**
|
||||||
Executable
+7
@@ -0,0 +1,7 @@
|
|||||||
|
#!/bin/bash
|
||||||
|
|
||||||
|
tsc --declaration
|
||||||
|
cp ./package.json ./dist
|
||||||
|
cp ./README.md ./dist
|
||||||
|
|
||||||
|
echo "Done"
|
||||||
Generated
+3724
File diff suppressed because it is too large.
Load diff
+6
-1
@@ -1,5 +1,5 @@
|
|||||||
{
|
{
|
||||||
"name": "@janishutz/oidc-login-server",
|
"name": "@janishutz/oidc-login-sdk-server",
|
||||||
"version": "1.0.0",
|
"version": "1.0.0",
|
||||||
"description": "Small wrapper on top of express-openid-connect to work together with my browser sdk",
|
"description": "Small wrapper on top of express-openid-connect to work together with my browser sdk",
|
||||||
"homepage": "https://github.com/janishutz/oidc-login-sdk-browser#readme",
|
"homepage": "https://github.com/janishutz/oidc-login-sdk-browser#readme",
|
||||||
@@ -24,5 +24,10 @@
|
|||||||
"eslint-plugin-vue": "^10.11.0",
|
"eslint-plugin-vue": "^10.11.0",
|
||||||
"globals": "^17.12.0",
|
"globals": "^17.12.0",
|
||||||
"typescript-eslint": "^8.70.0"
|
"typescript-eslint": "^8.70.0"
|
||||||
|
},
|
||||||
|
"dependencies": {
|
||||||
|
"@types/express": "^5.0.6",
|
||||||
|
"express": "^5.2.1",
|
||||||
|
"express-openid-connect": "^3.4.0"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -0,0 +1,59 @@
|
|||||||
|
import connect from 'express-openid-connect';
|
||||||
|
import express from 'express';
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Set up the sdk. It is recommended that you use a custom SessionStore, such as RedisStore for express-session
|
||||||
|
* Furthermore, see README for required environment variables
|
||||||
|
* @param app - Express application
|
||||||
|
* @param issuer - OIDC Issuer URL
|
||||||
|
* @param appURL - URL of this application
|
||||||
|
* @param authForAllRoutes - Whether or not to require authorization on all routes
|
||||||
|
* @param scopes - Scopes to request
|
||||||
|
* @param enableBackchannelLogout - Whether or not to enable backchannel logout. If true, must provide sessionStore
|
||||||
|
* @param userValidation - Function to validate the user
|
||||||
|
* @param sessionStore - RECOMMENDED: Use any express-session SessionStore, like the RedisStore
|
||||||
|
* @param extraOpts - Extra configuration options, or overwrite some set here
|
||||||
|
*/
|
||||||
|
export const configure = (
|
||||||
|
app: express.Application,
|
||||||
|
issuer: URL,
|
||||||
|
appURL: URL,
|
||||||
|
authForAllRoutes: boolean,
|
||||||
|
scopes: ( 'profile' | 'email' )[],
|
||||||
|
enableBackchannelLogout: boolean,
|
||||||
|
userValidation: ( req: express.Request, res: express.Response, session: connect.Session ) => Promise<connect.Session>,
|
||||||
|
sessionStore?: connect.SessionStore,
|
||||||
|
extraOpts?: connect.ConfigParams
|
||||||
|
) => {
|
||||||
|
app.use( connect.auth( {
|
||||||
|
'authRequired': authForAllRoutes,
|
||||||
|
'issuerBaseURL': issuer.href,
|
||||||
|
'baseURL': appURL.href,
|
||||||
|
'clientID': process.env.OIDC_CLIENT_ID,
|
||||||
|
'clientSecret': process.env.OIDC_CLIENT_SECRET,
|
||||||
|
'secret': process.env.SIGNING_SECRET,
|
||||||
|
'afterCallback': userValidation,
|
||||||
|
'authorizationParams': {
|
||||||
|
'scope': 'openid' + ( scopes.length > 0 ? ' ' + scopes.join( ' ' ) : '' ),
|
||||||
|
'response_type': 'code'
|
||||||
|
},
|
||||||
|
'backchannelLogout': enableBackchannelLogout,
|
||||||
|
'session': {
|
||||||
|
'store': sessionStore
|
||||||
|
},
|
||||||
|
'enableTelemetry': false,
|
||||||
|
'routes': {
|
||||||
|
'callback': '/auth/v2/verify',
|
||||||
|
'login': '/auth/v2/login',
|
||||||
|
'logout': '/auth/v2/logout',
|
||||||
|
'postLogoutRedirect': '/',
|
||||||
|
'backchannelLogout': '/auth/v2/logout'
|
||||||
|
},
|
||||||
|
...extraOpts
|
||||||
|
} ) );
|
||||||
|
|
||||||
|
app.get( '/auth/v2/check', connect.requiresAuth(), ( _req, res ) => res.sendStatus( 200 ) );
|
||||||
|
};
|
||||||
|
|
||||||
|
/** Re-Export of express-openid-connect's requiresAuth function */
|
||||||
|
export const requiresAuth = connect.requiresAuth;
|
||||||
Reference in new issue
Block a user