Skip to content

Commit 8babd64

Browse files
committed
initial commit
1 parent 0ba8568 commit 8babd64

File tree

4 files changed

+48
-25
lines changed

4 files changed

+48
-25
lines changed

plugins/arcgis/service/src/ArcGISConfig.ts

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -106,11 +106,14 @@ export interface UsernamePasswordAuthConfig {
106106
* Contains OAuth authentication configuration.
107107
*/
108108
export interface OAuthAuthConfig {
109+
109110
type: AuthType.OAuth
111+
110112
/**
111113
* The Client Id for OAuth
112114
*/
113115
clientId: string
116+
114117
/**
115118
* The redirectUri for OAuth
116119
*/
@@ -121,7 +124,7 @@ export interface OAuthAuthConfig {
121124
*/
122125
authToken?: string
123126

124-
/**
127+
/**
125128
* The expiration date for the temporary token
126129
*/
127130
authTokenExpires?: number

plugins/arcgis/service/src/ArcGISIdentityManagerFactory.ts

Lines changed: 31 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,14 @@
11
import { ArcGISIdentityManager } from "@esri/arcgis-rest-request"
22
import { ArcGISAuthConfig, AuthType, FeatureServiceConfig, OAuthAuthConfig, TokenAuthConfig, UsernamePasswordAuthConfig } from './ArcGISConfig'
33
import { HttpClient } from "./HttpClient";
4+
import { ObservationProcessor } from "./ObservationProcessor";
45

56
interface ArcGISIdentityManagerFactory {
6-
create(portal: string, server: string, config: ArcGISAuthConfig, httpClient?: HttpClient): Promise<ArcGISIdentityManager>
7+
create(portal: string, server: string, config: ArcGISAuthConfig, httpClient?: HttpClient, processor?: ObservationProcessor): Promise<ArcGISIdentityManager>
78
}
89

910
const OAuthIdentityManagerFactory: ArcGISIdentityManagerFactory = {
10-
async create(portal: string, server: string, auth: OAuthAuthConfig, httpClient: HttpClient): Promise<ArcGISIdentityManager> {
11+
async create(portal: string, server: string, auth: OAuthAuthConfig, httpClient: HttpClient, processor: ObservationProcessor): Promise<ArcGISIdentityManager> {
1112
console.debug('Client ID provided for authentication')
1213
const { clientId, authToken, authTokenExpires, refreshToken, refreshTokenExpires } = auth
1314

@@ -22,14 +23,30 @@ const OAuthIdentityManagerFactory: ArcGISIdentityManagerFactory = {
2223
} else if (refreshToken && new Date(refreshTokenExpires || 0) > new Date()) {
2324
// TODO: find a way without using constructor nor httpClient
2425
const url = `${portal}/oauth2/token?client_id=${clientId}&refresh_token=${refreshToken}&grant_type=refresh_token`
25-
const response = await httpClient.sendGet(url)
26-
// TODO: error handling
27-
return ArcGISIdentityManager.fromToken({
28-
clientId: clientId,
29-
token: response.access_token,
30-
portal: portal
31-
});
32-
// TODO: update authToken to new token
26+
try {
27+
const response = await httpClient.sendGet(url)
28+
// Update authToken to new token
29+
const config = await processor.safeGetConfig();
30+
let service = config.featureServices.find(service => service.url === portal)?.auth as OAuthAuthConfig;
31+
const date = new Date();
32+
date.setSeconds(date.getSeconds() + response.expires_in || 0);
33+
service = {
34+
...service,
35+
authToken: response.access_token,
36+
authTokenExpires: date.getTime()
37+
}
38+
39+
await processor.putConfig(config)
40+
return ArcGISIdentityManager.fromToken({
41+
clientId: clientId,
42+
token: response.access_token,
43+
tokenExpires: date,
44+
portal: portal
45+
});
46+
} catch (error) {
47+
throw new Error('Error occurred when using refresh token')
48+
}
49+
3350
} else {
3451
// TODO the config, we need to let the user know UI side they need to authenticate again
3552
throw new Error('Refresh token missing or expired')
@@ -46,7 +63,7 @@ const TokenIdentityManagerFactory: ArcGISIdentityManagerFactory = {
4663
server: server,
4764
// TODO: what do we really want to do here? esri package seems to need this optional parameter.
4865
// Use authTokenExpires if defined, otherwise set to now plus a day
49-
tokenExpires: auth.authTokenExpires ? new Date(auth.authTokenExpires) : new Date(Date.now() + 24 * 60 * 60 * 1000)
66+
tokenExpires: auth.authTokenExpires ? new Date(auth.authTokenExpires) : new Date(Date.now() + 24 * 60 * 60 * 1000)
5067
})
5168
return identityManager
5269
}
@@ -68,7 +85,8 @@ const authConfigMap: { [key: string]: ArcGISIdentityManagerFactory } = {
6885

6986
export function getIdentityManager(
7087
config: FeatureServiceConfig,
71-
httpClient: HttpClient // TODO remove in favor of an open source lib like axios
88+
httpClient: HttpClient, // TODO remove in favor of an open source lib like axios
89+
processor: ObservationProcessor
7290
): Promise<ArcGISIdentityManager> {
7391
const auth = config.auth
7492
const authType = config.auth?.type
@@ -79,7 +97,7 @@ export function getIdentityManager(
7997
if (!factory) {
8098
throw new Error(`No factory found for type ${authType}`)
8199
}
82-
return factory.create(getPortalUrl(config.url), getServerUrl(config.url), auth, httpClient)
100+
return factory.create(getPortalUrl(config.url), getServerUrl(config.url), auth, httpClient, processor)
83101
}
84102

85103

plugins/arcgis/service/src/index.ts

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -120,7 +120,7 @@ const arcgisPluginHooks: InitPluginHook<typeof InjectedServices> = {
120120
}
121121

122122
await processor.putConfig(config)
123-
123+
// TODO: This seems like a bad idea to send the access tokens to the front end. It has no use for them and could potentially be a security concern
124124
res.send(`
125125
<html>
126126
<head>
@@ -181,7 +181,7 @@ const arcgisPluginHooks: InitPluginHook<typeof InjectedServices> = {
181181
try {
182182
const httpClient = new HttpClient(console)
183183
// Create the IdentityManager instance to validate credentials
184-
await getIdentityManager(service!, httpClient)
184+
await getIdentityManager(service!, httpClient, processor)
185185
let existingService = config.featureServices.find(service => service.url === url)
186186
if (existingService) {
187187
existingService = { ...existingService }
@@ -206,7 +206,7 @@ const arcgisPluginHooks: InitPluginHook<typeof InjectedServices> = {
206206

207207
const httpClient = new HttpClient(console)
208208
try {
209-
const identityManager = await getIdentityManager(featureService, httpClient)
209+
const identityManager = await getIdentityManager(featureService, httpClient, processor)
210210
const response = await request(url, {
211211
authentication: identityManager
212212
})

plugins/arcgis/web-app/projects/main/src/lib/arc.service.ts

Lines changed: 10 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -61,15 +61,17 @@ export class ArcService implements ArcServiceInterface {
6161
const oauthWindow = window.open(url, "_blank");
6262

6363
const listener = (event: any) => {
64-
window.removeEventListener('message', listener, false);
65-
66-
if (event.origin !== window.location.origin) {
67-
subject.error('target origin mismatch')
64+
if (event.data.url) {
65+
window.removeEventListener('message', listener, false);
66+
67+
if (event.origin !== window.location.origin) {
68+
subject.error('target origin mismatch')
69+
}
70+
71+
subject.next(event.data)
72+
73+
oauthWindow?.close();
6874
}
69-
70-
subject.next(event.data)
71-
72-
oauthWindow?.close();
7375
}
7476

7577
window.addEventListener('message', listener, false);

0 commit comments

Comments
 (0)