Skip to content

Commit e86a22f

Browse files
Add option to add HTTP proxy for OAuth (#742)
* configure http proxy * configure http proxy in config file * Use setAgent as a method, not a value --------- Co-authored-by: Garrett Stevens <stevens.garrett.j@gmail.com>
1 parent ef8b475 commit e86a22f

File tree

6 files changed

+59
-0
lines changed

6 files changed

+59
-0
lines changed

packages/apollo-collaboration-server/package.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -63,6 +63,7 @@
6363
"express": "^4.18.0",
6464
"express-session": "^1.17.3",
6565
"generic-filehandle": "^3.0.0",
66+
"https-proxy-agent": "^7.0.6",
6667
"joi": "^17.7.0",
6768
"material-ui-popup-state": "^5.0.4",
6869
"mobx": "^6.6.1",

packages/apollo-collaboration-server/src/app.module.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -108,6 +108,7 @@ const validationSchema = Joi.object({
108108
})
109109
.default(''),
110110
PLUGIN_URLS_FILE: Joi.string(),
111+
OAUTH_HTTP_PROXY: Joi.string(),
111112
})
112113
.xor('MONGODB_URI', 'MONGODB_URI_FILE')
113114
.oxor('GOOGLE_CLIENT_ID', 'GOOGLE_CLIENT_ID_FILE')

packages/apollo-collaboration-server/src/utils/strategies/google.strategy.ts

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@ import fs from 'node:fs'
33
import { Injectable, Logger } from '@nestjs/common'
44
import { ConfigService } from '@nestjs/config'
55
import { PassportStrategy } from '@nestjs/passport'
6+
import { HttpsProxyAgent } from 'https-proxy-agent'
67
import { Profile, Strategy } from 'passport-google-oauth20'
78

89
import { AuthenticationService } from '../../authentication/authentication.service'
@@ -14,6 +15,7 @@ interface ConfigValues {
1415
GOOGLE_CLIENT_SECRET_FILE?: string
1516
URL: string
1617
PORT: number
18+
OAUTH_HTTP_PROXY?: string
1719
}
1820

1921
@Injectable()
@@ -62,6 +64,21 @@ export class GoogleStrategy extends PassportStrategy(Strategy) {
6264
scope: ['email', 'profile'],
6365
store: true,
6466
})
67+
68+
// Apply proxy to OAuth2 instance
69+
const proxy = configService.get('OAUTH_HTTP_PROXY', { infer: true })
70+
if (proxy) {
71+
const agent = new HttpsProxyAgent(proxy)
72+
73+
// Access the internal OAuth2 instance and set the agent
74+
// eslint-disable-next-line @typescript-eslint/no-unsafe-assignment, @typescript-eslint/no-explicit-any, @typescript-eslint/no-unsafe-member-access
75+
const oauth2 = (this as any)._oauth2
76+
if (oauth2) {
77+
// eslint-disable-next-line @typescript-eslint/no-unsafe-member-access, @typescript-eslint/no-unsafe-call
78+
oauth2.setAgent(agent)
79+
this.logger.debug(`GoogleStrategy configured to use proxy: ${proxy}`)
80+
}
81+
}
6582
}
6683

6784
async validate(accessToken: string, refreshToken: string, profile: Profile) {

packages/apollo-collaboration-server/src/utils/strategies/microsoft.strategy.ts

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@ import fs from 'node:fs'
33
import { Injectable, Logger } from '@nestjs/common'
44
import { ConfigService } from '@nestjs/config'
55
import { PassportStrategy } from '@nestjs/passport'
6+
import { HttpsProxyAgent } from 'https-proxy-agent'
67
import { Strategy } from 'passport-microsoft'
78

89
import { AuthenticationService } from '../../authentication/authentication.service'
@@ -22,6 +23,7 @@ interface ConfigValues {
2223
MICROSOFT_CLIENT_SECRET_FILE?: string
2324
URL: string
2425
PORT: number
26+
OAUTH_HTTP_PROXY?: string
2527
}
2628

2729
@Injectable()
@@ -72,6 +74,23 @@ export class MicrosoftStrategy extends PassportStrategy(Strategy) {
7274
scope: ['user.read'],
7375
store: true,
7476
})
77+
78+
// Apply proxy to OAuth2 instance
79+
const proxy = configService.get('OAUTH_HTTP_PROXY', { infer: true })
80+
if (proxy) {
81+
const agent = new HttpsProxyAgent(proxy)
82+
83+
// Access the internal OAuth2 instance and set the agent
84+
// eslint-disable-next-line @typescript-eslint/no-unsafe-assignment, @typescript-eslint/no-explicit-any, @typescript-eslint/no-unsafe-member-access
85+
const oauth2 = (this as any)._oauth2
86+
if (oauth2) {
87+
// eslint-disable-next-line @typescript-eslint/no-unsafe-member-access, @typescript-eslint/no-unsafe-call
88+
oauth2.setAgent(agent)
89+
this.logger.debug(
90+
`Microsoft Strategy configured to use proxy: ${proxy}`,
91+
)
92+
}
93+
}
7594
}
7695

7796
async validate(accessToken: string, refreshToken: string, profile: Profile) {

packages/website/docs/02-installation/04-configuration-options.md

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -105,4 +105,7 @@ MICROSOFT_CLIENT_SECRET=client_secret_here
105105
# Alternatively, can be a path to a file with a list of plugin URLs, one URL per
106106
# line
107107
# PLUGIN_URLS_FILE=/data/plugin-urls
108+
109+
# HTTP/HTTPS proxy for OAuth requests, if your server is behind a proxy
110+
# OAUTH_HTTP_PROXY=http://proxy.example.com:8080
108111
```

yarn.lock

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -409,6 +409,7 @@ __metadata:
409409
express: "npm:^4.18.0"
410410
express-session: "npm:^1.17.3"
411411
generic-filehandle: "npm:^3.0.0"
412+
https-proxy-agent: "npm:^7.0.6"
412413
jest: "npm:^29.6.2"
413414
joi: "npm:^17.7.0"
414415
material-ui-popup-state: "npm:^5.0.4"
@@ -11513,6 +11514,13 @@ __metadata:
1151311514
languageName: node
1151411515
linkType: hard
1151511516

11517+
"agent-base@npm:^7.1.2":
11518+
version: 7.1.4
11519+
resolution: "agent-base@npm:7.1.4"
11520+
checksum: 10c0/c2c9ab7599692d594b6a161559ada307b7a624fa4c7b03e3afdb5a5e31cd0e53269115b620fcab024c5ac6a6f37fa5eb2e004f076ad30f5f7e6b8b671f7b35fe
11521+
languageName: node
11522+
linkType: hard
11523+
1151611524
"agentkeepalive@npm:^4.1.3, agentkeepalive@npm:^4.2.1":
1151711525
version: 4.5.0
1151811526
resolution: "agentkeepalive@npm:4.5.0"
@@ -19663,6 +19671,16 @@ __metadata:
1966319671
languageName: node
1966419672
linkType: hard
1966519673

19674+
"https-proxy-agent@npm:^7.0.6":
19675+
version: 7.0.6
19676+
resolution: "https-proxy-agent@npm:7.0.6"
19677+
dependencies:
19678+
agent-base: "npm:^7.1.2"
19679+
debug: "npm:4"
19680+
checksum: 10c0/f729219bc735edb621fa30e6e84e60ee5d00802b8247aac0d7b79b0bd6d4b3294737a337b93b86a0bd9e68099d031858a39260c976dc14cdbba238ba1f8779ac
19681+
languageName: node
19682+
linkType: hard
19683+
1966619684
"human-signals@npm:^1.1.1":
1966719685
version: 1.1.1
1966819686
resolution: "human-signals@npm:1.1.1"

0 commit comments

Comments
 (0)