oauth2-cli 0.8.9 → 1.0.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1,44 +0,0 @@
1
- /**
2
- * Reaching into the bowels of openid-client to be able to fully de-serialize a
3
- * serialized token response
4
- */
5
- import * as oauth from 'oauth4webapi';
6
- /** @see https://github.com/panva/openid-client/blob/79386b7f120dc9bdc7606886a26e4ea7d011ee51/src/index.ts#L1981-L2016 */
7
- function getHelpers(response) {
8
- let exp = undefined;
9
- if (response.expires_in !== undefined) {
10
- const now = new Date();
11
- now.setSeconds(now.getSeconds() + response.expires_in);
12
- exp = now.getTime();
13
- }
14
- return {
15
- expiresIn: {
16
- __proto__: null,
17
- value() {
18
- if (exp) {
19
- const now = Date.now();
20
- if (exp > now) {
21
- return Math.floor((exp - now) / 1000);
22
- }
23
- return 0;
24
- }
25
- return undefined;
26
- }
27
- },
28
- claims: {
29
- __proto__: null,
30
- value() {
31
- try {
32
- return oauth.getValidatedIdTokenClaims(this);
33
- }
34
- catch {
35
- return undefined;
36
- }
37
- }
38
- }
39
- };
40
- }
41
- /** @see https://github.com/panva/openid-client/blob/79386b7f120dc9bdc7606886a26e4ea7d011ee51/src/index.ts#L2018-L2022 */
42
- export function addHelpers(response) {
43
- Object.defineProperties(response, getHelpers(response));
44
- }
@@ -1,75 +0,0 @@
1
- import { PathString } from '@battis/descriptive-types';
2
- import { Request, Response } from 'express';
3
- import { Session } from './Session.js';
4
- export type WebServerOptions = {
5
- session: Session;
6
- /** See {@link WebServer.setViews setViews()} */
7
- views?: PathString;
8
- /**
9
- * Local web server authorize endpoint
10
- *
11
- * This is separate and distinct from the OpenID/OAuth server's authorization
12
- * endpoint. This endpoint is the first path that the user is directed to in
13
- * their browser. It can present an explanation of what is being authorized
14
- * and why. By default it redirects to the OpenID/OAuth server's authorization
15
- * URL, the first step in the Authorization Code Grant flow.
16
- */
17
- authorize_endpoint?: PathString;
18
- /**
19
- * The number of milliseconds of inactivity before a socket is presumed to
20
- * have timed out. This can be reduced to limit potential wait times during
21
- * interactive authentication, but must still be long enough to allow time for
22
- * the authorization code to be exchanged for an access token.
23
- *
24
- * Defaults to 1000 milliseconds
25
- */
26
- timeout?: number;
27
- };
28
- export declare const DEFAULT_AUTHORIZE_ENDPOINT = "/oauth2-cli/authorize";
29
- export interface WebServerInterface {
30
- /** See {@link WebServerOptions} */
31
- readonly authorization_endpoint: PathString;
32
- /** Shut down web server */
33
- close(): Promise<void>;
34
- }
35
- /**
36
- * Minimal HTTP server running on localhost to handle the redirect step of
37
- * OpenID/OAuth flows
38
- */
39
- export declare class WebServer implements WebServerInterface {
40
- private static activePorts;
41
- protected readonly session: Session;
42
- private views?;
43
- private packageViews;
44
- protected readonly port: string;
45
- readonly authorization_endpoint: PathString;
46
- private server;
47
- constructor({ session, views, authorize_endpoint, timeout }: WebServerOptions);
48
- /**
49
- * Set the path to folder of *.ejs templates
50
- *
51
- * Expected templates include:
52
- *
53
- * - `authorize.ejs` presents information prior to the authorization to the
54
- * user, and the user must follow `authorize_url` data property to
55
- * interactively initiate authorization
56
- * - `complete.ejs` presented to user upon successful completion of
57
- * authorization flow
58
- * - `error.ejs` presented to user upon receipt of an error from the server,
59
- * includes `error` as data
60
- *
61
- * `complete.ejs` and `error.ejs` are included with oauth2-cli and those
62
- * templates will be used if `ejs` is imported but no replacement templates
63
- * are found.
64
- *
65
- * @param views Should be an absolute path
66
- */
67
- setViews(views: PathString): void;
68
- protected render(res: Response, template: string, data?: Record<string, unknown>): Promise<boolean>;
69
- /** Handles request to `/authorize` */
70
- protected handleAuthorizationEndpoint(req: Request, res: Response): Promise<void>;
71
- /** Handles request to `redirect_uri` */
72
- protected handleRedirect(req: Request, res: Response): Promise<void>;
73
- /** Shut down web server */
74
- close(): Promise<void>;
75
- }
package/dist/WebServer.js DELETED
@@ -1,123 +0,0 @@
1
- import express from 'express';
2
- import * as gcrtl from 'gcrtl';
3
- import fs from 'node:fs';
4
- import path from 'node:path';
5
- import * as requestish from 'requestish';
6
- let ejs = undefined;
7
- try {
8
- ejs = (await import('ejs')).default;
9
- }
10
- catch (_) {
11
- // ignore error
12
- }
13
- export const DEFAULT_AUTHORIZE_ENDPOINT = '/oauth2-cli/authorize';
14
- /**
15
- * Minimal HTTP server running on localhost to handle the redirect step of
16
- * OpenID/OAuth flows
17
- */
18
- export class WebServer {
19
- static activePorts = [];
20
- session;
21
- views;
22
- packageViews = '../views';
23
- port;
24
- authorization_endpoint;
25
- server;
26
- constructor({ session, views, authorize_endpoint = DEFAULT_AUTHORIZE_ENDPOINT, timeout = 1000 // milliseconds
27
- }) {
28
- this.session = session;
29
- this.authorization_endpoint = authorize_endpoint;
30
- this.views = views;
31
- const url = requestish.URL.from(this.session.redirect_uri);
32
- this.port = url.port;
33
- if (WebServer.activePorts.includes(this.port)) {
34
- throw new Error(`Another process is already running at http://localhost:${url.port}.`, { cause: { activePorts: WebServer.activePorts } });
35
- }
36
- WebServer.activePorts.push(this.port);
37
- const app = express();
38
- app.get(this.authorization_endpoint, this.handleAuthorizationEndpoint.bind(this));
39
- app.get(gcrtl.path(url), this.handleRedirect.bind(this));
40
- this.server = app.listen(gcrtl.port(url));
41
- this.server.timeout = timeout;
42
- this.server.keepAliveTimeout = 0;
43
- this.server.keepAliveTimeoutBuffer = 0;
44
- }
45
- /**
46
- * Set the path to folder of *.ejs templates
47
- *
48
- * Expected templates include:
49
- *
50
- * - `authorize.ejs` presents information prior to the authorization to the
51
- * user, and the user must follow `authorize_url` data property to
52
- * interactively initiate authorization
53
- * - `complete.ejs` presented to user upon successful completion of
54
- * authorization flow
55
- * - `error.ejs` presented to user upon receipt of an error from the server,
56
- * includes `error` as data
57
- *
58
- * `complete.ejs` and `error.ejs` are included with oauth2-cli and those
59
- * templates will be used if `ejs` is imported but no replacement templates
60
- * are found.
61
- *
62
- * @param views Should be an absolute path
63
- */
64
- setViews(views) {
65
- this.views = views;
66
- }
67
- async render(res, template, data = {}) {
68
- const name = this.session.client.clientName();
69
- async function attemptToRender(views) {
70
- if (ejs && views) {
71
- const viewPath = path.resolve(import.meta.dirname, views, template);
72
- if (fs.existsSync(viewPath)) {
73
- res.send(await ejs.renderFile(viewPath, { name, ...data }));
74
- return true;
75
- }
76
- }
77
- return false;
78
- }
79
- return ((await attemptToRender(this.views)) ||
80
- (await attemptToRender(this.packageViews)));
81
- }
82
- /** Handles request to `/authorize` */
83
- async handleAuthorizationEndpoint(req, res) {
84
- const authorization_url = await this.session.getAuthorizationUrl();
85
- if (!(await this.render(res, 'authorize.ejs', { authorization_url }))) {
86
- res.redirect(authorization_url);
87
- res.end();
88
- }
89
- }
90
- /** Handles request to `redirect_uri` */
91
- async handleRedirect(req, res) {
92
- try {
93
- await this.session.handleAuthorizationCodeRedirect(req);
94
- if (!(await this.render(res, 'complete.ejs'))) {
95
- res.send(`${this.session.client.clientName()} authorization complete. You may close this window.`);
96
- }
97
- }
98
- catch (error) {
99
- if (!(await this.render(res, 'error.ejs', { error }))) {
100
- res.send({
101
- client: this.session.client.clientName(),
102
- error
103
- });
104
- }
105
- }
106
- }
107
- /** Shut down web server */
108
- async close() {
109
- return new Promise((resolve, reject) => {
110
- this.server.close((cause) => {
111
- if (cause) {
112
- reject(new Error(`Error shutting down ${this.session.client.clientName()} out-of-band redirect web server`, {
113
- cause
114
- }));
115
- }
116
- else {
117
- WebServer.activePorts.splice(WebServer.activePorts.indexOf(this.port), 1);
118
- resolve();
119
- }
120
- });
121
- });
122
- }
123
- }
File without changes
File without changes