-
Notifications
You must be signed in to change notification settings - Fork 409
Implemented IID Delete API #142
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from 6 commits
bbc810a
8c2ce27
0e54c79
2960039
fc66e80
e242da6
7d99cdd
283d208
79afba3
1ae5ea1
f46a53f
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,111 @@ | ||
/*! | ||
* Copyright 2017 Google Inc. | ||
* | ||
* Licensed under the Apache License, Version 2.0 (the "License"); | ||
* you may not use this file except in compliance with the License. | ||
* You may obtain a copy of the License at | ||
* | ||
* http://www.apache.org/licenses/LICENSE-2.0 | ||
* | ||
* Unless required by applicable law or agreed to in writing, software | ||
* distributed under the License is distributed on an "AS IS" BASIS, | ||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
* See the License for the specific language governing permissions and | ||
* limitations under the License. | ||
*/ | ||
|
||
import {FirebaseApp} from '../firebase-app'; | ||
import {FirebaseError, FirebaseInstanceIdError, InstanceIdClientErrorCode} from '../utils/error'; | ||
import { | ||
HttpMethod, SignedApiRequestHandler, ApiSettings, | ||
} from '../utils/api-request'; | ||
|
||
import * as validator from '../utils/validator'; | ||
|
||
/** Firebase IID backend host. */ | ||
const FIREBASE_IID_HOST = 'console.firebase.google.com'; | ||
/** Firebase IID backend port number. */ | ||
const FIREBASE_IID_PORT = 443; | ||
/** Firebase IID backend path. */ | ||
const FIREBASE_IID_PATH = '/v1/'; | ||
/** Firebase IID request timeout duration in milliseconds. */ | ||
const FIREBASE_IID_TIMEOUT = 10000; | ||
|
||
/** | ||
* Class that provides mechanism to send requests to the Firebase Auth backend endpoints. | ||
*/ | ||
export class FirebaseInstanceIdRequestHandler { | ||
|
||
private host: string = FIREBASE_IID_HOST; | ||
private port: number = FIREBASE_IID_PORT; | ||
private timeout: number = FIREBASE_IID_TIMEOUT; | ||
private signedApiRequestHandler: SignedApiRequestHandler; | ||
private path: string; | ||
|
||
/** | ||
* @param {FirebaseApp} app The app used to fetch access tokens to sign API requests. | ||
* @param {string} projectId A Firebase project ID string. | ||
* | ||
* @constructor | ||
*/ | ||
constructor(app: FirebaseApp, projectId: string) { | ||
this.signedApiRequestHandler = new SignedApiRequestHandler(app); | ||
this.path = FIREBASE_IID_PATH + `project/${projectId}/instanceId/`; | ||
} | ||
|
||
public deleteInstanceId(instanceId: string): Promise<Object> { | ||
if (!validator.isNonEmptyString(instanceId)) { | ||
return Promise.reject(new FirebaseInstanceIdError( | ||
InstanceIdClientErrorCode.INVALID_INSTANCE_ID, | ||
'Instance ID must be a non-empty string.' | ||
)); | ||
} | ||
return this.invokeRequestHandler(new ApiSettings(instanceId, 'DELETE')); | ||
} | ||
|
||
/** | ||
* Invokes the request handler based on the API settings object passed. | ||
* | ||
* @param {ApiSettings} apiSettings The API endpoint settings to apply to request and response. | ||
* @param {Object} requestData The request data. | ||
* @return {Promise<Object>} A promise that resolves with the response. | ||
*/ | ||
private invokeRequestHandler(apiSettings: ApiSettings): Promise<Object> { | ||
let path: string = this.path + apiSettings.getEndpoint(); | ||
let httpMethod: HttpMethod = apiSettings.getHttpMethod(); | ||
return Promise.resolve() | ||
.then(() => { | ||
return this.signedApiRequestHandler.sendRequest( | ||
this.host, this.port, path, httpMethod, undefined, undefined, this.timeout); | ||
}) | ||
.then((response) => { | ||
return response; | ||
}) | ||
.catch((response) => { | ||
let error; | ||
if (typeof response === 'object' && 'error' in response) { | ||
error = response.error; | ||
} else { | ||
error = response; | ||
} | ||
|
||
if (error instanceof FirebaseError) { | ||
// In case of timeouts and other network errors, the API request handler returns a | ||
// FirebaseError wrapped in the response. Simply throw it here. | ||
throw error; | ||
} | ||
|
||
let message: string; | ||
if (response.statusCode === 404) { | ||
message = 'Failed to find the instance ID: ' + apiSettings.getEndpoint(); | ||
} else if (response.statusCode === 429) { | ||
message = 'Request throttled out by the backend server'; | ||
} else if (response.statusCode === 500) { | ||
message = 'Internal server error'; | ||
} else { | ||
message = JSON.stringify(error); | ||
} | ||
throw new FirebaseInstanceIdError(InstanceIdClientErrorCode.API_ERROR, message); | ||
}); | ||
} | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,96 @@ | ||
/*! | ||
* Copyright 2017 Google Inc. | ||
* | ||
* Licensed under the Apache License, Version 2.0 (the "License"); | ||
* you may not use this file except in compliance with the License. | ||
* You may obtain a copy of the License at | ||
* | ||
* http://www.apache.org/licenses/LICENSE-2.0 | ||
* | ||
* Unless required by applicable law or agreed to in writing, software | ||
* distributed under the License is distributed on an "AS IS" BASIS, | ||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
* See the License for the specific language governing permissions and | ||
* limitations under the License. | ||
*/ | ||
|
||
import {FirebaseApp} from '../firebase-app'; | ||
import {FirebaseInstanceIdError, InstanceIdClientErrorCode} from '../utils/error'; | ||
import {FirebaseServiceInterface, FirebaseServiceInternalsInterface} from '../firebase-service'; | ||
import {FirebaseInstanceIdRequestHandler} from './instance-id-request'; | ||
|
||
import * as utils from '../utils/index'; | ||
import * as validator from '../utils/validator'; | ||
|
||
/** | ||
* Internals of an InstanceId service instance. | ||
*/ | ||
class InstanceIdInternals implements FirebaseServiceInternalsInterface { | ||
/** | ||
|
||
* Deletes the service and its associated resources. | ||
* | ||
* @return {Promise<()>} An empty Promise that will be fulfilled when the service is deleted. | ||
*/ | ||
public delete(): Promise<void> { | ||
// There are no resources to clean up | ||
|
||
return Promise.resolve(undefined); | ||
} | ||
} | ||
|
||
export class InstanceId implements FirebaseServiceInterface { | ||
public INTERNAL: InstanceIdInternals = new InstanceIdInternals(); | ||
|
||
|
||
private app_: FirebaseApp; | ||
|
||
private requestHandler: FirebaseInstanceIdRequestHandler; | ||
|
||
/** | ||
* @param {Object} app The app for this Auth service. | ||
|
||
* @constructor | ||
*/ | ||
constructor(app: FirebaseApp) { | ||
if (!validator.isNonNullObject(app) || !('options' in app)) { | ||
throw new FirebaseInstanceIdError( | ||
InstanceIdClientErrorCode.INVALID_ARGUMENT, | ||
'First argument passed to admin.instanceId() must be a valid Firebase app instance.' | ||
); | ||
} | ||
|
||
const projectId: string = utils.getProjectId(app); | ||
if (!validator.isNonEmptyString(projectId)) { | ||
// Assert for an explicit projct ID (either via AppOptions or the cert itself). | ||
throw new FirebaseInstanceIdError( | ||
InstanceIdClientErrorCode.INVALID_PROJECT_ID, | ||
'Failed to determine project ID for InstanceId. Initialize the ' | ||
+ 'SDK with service account credentials or set project ID as an app option. ' | ||
+ 'Alternatively set the GCLOUD_PROJECT environment variable.', | ||
); | ||
} | ||
|
||
this.app_ = app; | ||
this.requestHandler = new FirebaseInstanceIdRequestHandler(app, projectId); | ||
} | ||
|
||
/** | ||
* Deletes the specified instance ID from Firebase. This can be used to delete an instance ID | ||
* and associated user data from a Firebase project, pursuant to the General Data Protection | ||
* Regulation (GDPR). | ||
* | ||
* @param {string} instanceId The instance ID to be deleted | ||
* @return {Promise<void>} A promise that resolves when the instance ID is successfully deleted. | ||
*/ | ||
public deleteInstanceId(instanceId: string): Promise<void> { | ||
return this.requestHandler.deleteInstanceId(instanceId) | ||
.then((result) => { | ||
// Return nothing on success | ||
}); | ||
} | ||
|
||
/** | ||
* Returns the app associated with this InstanceId instance. | ||
* | ||
* @return {FirebaseApp} The app associated with this InstanceId instance. | ||
*/ | ||
get app(): FirebaseApp { | ||
return this.app_; | ||
} | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -22,7 +22,7 @@ import {OutgoingHttpHeaders} from 'http'; | |
import https = require('https'); | ||
|
||
/** Http method type definition. */ | ||
export type HttpMethod = 'GET' | 'POST'; | ||
export type HttpMethod = 'GET' | 'POST' | 'DELETE'; | ||
/** API callback function type definition. */ | ||
export type ApiCallbackFunction = (data: Object) => void; | ||
|
||
|
@@ -224,11 +224,16 @@ export class SignedApiRequestHandler extends HttpRequestHandler { | |
port: number, | ||
path: string, | ||
httpMethod: HttpMethod, | ||
data: Object, | ||
headers: Object, | ||
timeout: number): Promise<Object> { | ||
data?: Object, | ||
headers?: Object, | ||
timeout?: number): Promise<Object> { | ||
return this.app_.INTERNAL.getToken().then((accessTokenObj) => { | ||
let headersCopy: Object = deepCopy(headers); | ||
let headersCopy: Object; | ||
|
||
if (typeof headers !== 'undefined') { | ||
headersCopy = deepCopy(headers); | ||
} else { | ||
headersCopy = {}; | ||
} | ||
let authorizationHeaderKey = 'Authorization'; | ||
headersCopy[authorizationHeaderKey] = 'Bearer ' + accessTokenObj.accessToken; | ||
return super.sendRequest(host, port, path, httpMethod, data, headersCopy, timeout); | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Update comment: Firebase IID backend endpoints.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Done