Created
April 13, 2020 19:54
-
-
Save eoger/73d2b24eedf4ec85e23e17a16e792d33 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
class RustFxAccount { | |
/** | |
* Create a new unauthenticated instance of FxA from scratch. | |
* @param {String} fxaServer Content URL of the remote Firefox Accounts server. | |
* @param {string} clientId OAuth client_id of the application. | |
* @param {string} redirectUri Redirection URL to be navigated to at the end of the OAuth login flow. | |
* @param {string} [tokenServerUrlOverride] Override the token server URL: used by self-hosters of Sync. | |
*/ | |
constructor({ | |
fxaServer, | |
clientId, | |
redirectUri, | |
tokenServerUrlOverride = null | |
}) { | |
// Cool | |
} | |
/** | |
* Restore a previous instance of `RustFxAccount` from a | |
* serialized state (obtained with `toJSON(...)`). | |
* @returns {Promise<RustFxAccount>} | |
*/ | |
static fromJSON(json) { | |
// Beans | |
} | |
/** | |
* Serialize the state of a `RustFxAccount` instance. It can be restored | |
* later with `fromJSON(...)`. It is the responsability of the caller to | |
* persist that serialized state regularly (after operations that mutate | |
* `RustFxAccount`) in a **secure** location. | |
* @returns {Promise<string>} The JSON representation of the state. | |
*/ | |
async toJSON() { | |
return "foobar" | |
} | |
/** | |
* Request a OAuth token by starting a new OAuth flow. | |
* | |
* Once the user has confirmed the authorization grant, they will get redirected to `redirect_url`: | |
* the caller must intercept that redirection, extract the `code` and `state` query parameters and call | |
* `completeOAuthFlow(...)` to complete the flow. | |
* | |
* @param {[string]} scopes | |
* @returns {Promise<string>} a URL string that the caller should navigate to. | |
*/ | |
async beginOAuthFlow(scopes) { | |
return "https://mozilla.com" | |
} | |
/** | |
* Start a supp-side pairing flow by providing the | |
* URL displayed by the Auth side. | |
* | |
* @param {string} pairingUrl | |
* @param {[string]} scopes | |
* @returns {Promise<string>} a URL string that the caller should navigate to. | |
*/ | |
async beginPairingFlow(pairingUrl, scopes) { | |
return "https://mozilla.com" | |
} | |
/** | |
* Complete an OAuth flow initiated by `beginOAuthFlow(...)`. | |
* | |
* @param {string} code | |
* @param {string} state | |
* @throws if there was an error during the login flow. | |
*/ | |
async completeOAuthFlow(code, state) { | |
} | |
/** | |
* Try to get an OAuth access token. | |
* | |
* @typedef {Object} AccessTokenInfo | |
* @property {string} scope | |
* @property {string} token | |
* @property {ScopedKey} [key] | |
* @property {Date} expiresAt | |
* | |
* @typedef {Object} ScopedKey | |
* @property {string} kty | |
* @property {string} scope | |
* @property {string} k | |
* @property {string} kid | |
* | |
* @param {string} scope Single OAuth scope | |
* @param {Number} ttl Time in seconds for which the token will be used. | |
* @returns {Promise<AccessTokenInfo>} | |
* @throws if we couldn't provide an access token | |
* for this scope. The caller should then start the OAuth Flow again with | |
* the desired scope. | |
*/ | |
async getAccessToken(scope, ttl) { | |
return { | |
scope: "profile", | |
token: "deadbeef", | |
key: { | |
kty: "aaaa", | |
scope: "oldsync", | |
k: "huh", | |
kid: "123abc" | |
}, | |
expiresAt: Date.now(), | |
} | |
} | |
/** | |
* Get the session token if held. | |
* | |
* @returns {Promise<string>} | |
* @throws if a session token is not being held. | |
*/ | |
async getSessionToken() { | |
return "abcdef"; | |
} | |
/** | |
* Check whether the currently held refresh token is active. | |
* | |
* @typedef {Object} IntrospectInfo | |
* @property {boolean} active | |
* | |
* @returns {Promise<IntrospectInfo>} | |
*/ | |
async checkAuthorizationStatus() { | |
return {active: true} | |
} | |
/* | |
* This method should be called when a request made with | |
* an OAuth token failed with an authentication error. | |
* It clears the internal cache of OAuth access tokens, | |
* so the caller can try to call `getAccessToken` or `getProfile` | |
* again. | |
*/ | |
async clearAccessTokenCache() { | |
// Huh | |
} | |
/* | |
* Disconnect from the account and optionaly destroy our device record. | |
* `beginOAuthFlow(...)` will need to be called to reconnect. | |
*/ | |
async disconnect() { | |
// Ho? | |
} | |
/** | |
* Gets the logged-in user profile. | |
* | |
* @typedef {Object} Profile | |
* @property {string} uid | |
* @property {string} email | |
* @property {Avatar} [avatar] | |
* @property {string} [displayName] | |
* | |
* @typedef {Object} Avatar | |
* @property {string} url | |
* @property {boolean} isDefault | |
* | |
* @returns {Promise<Profile>} | |
* @throws if no suitable access token was found to make this call. | |
* The caller should then start the OAuth login flow again with | |
* at least the `profile` scope. | |
*/ | |
async getProfile() { | |
return { | |
uid: "12345", | |
email: "foo@bar.com", | |
avatar: { | |
isDefault: false, | |
url: "https://barbar.foo/img.jpg", | |
}, | |
displayName: null, | |
} | |
} | |
/** | |
* Start a migration process from a browser-id based authenticated account. | |
* | |
* @returns {Promise<boolean>} true if the migration was successful. | |
*/ | |
async migrateFromSessionToken(sessionToken, kSync, kXCS) { | |
return true | |
} | |
/** | |
* Call this function after migrateFromSessionToken is un-successful | |
* (or after app startup) to figure out if we can call `retryMigrateFromSessionToken`. | |
* | |
* @returns {Promise<boolean>} true if resume the migration is possible. | |
*/ | |
async isInMigrationState() { | |
return false | |
} | |
/** | |
* Retry a migration that failed earlier because of transient reasons. | |
* | |
* @returns {Promise<boolean>} true if the migration was successful. | |
*/ | |
async retryMigrateFromSessionToken(sessionToken, kSync, kXCS) { | |
return true | |
} | |
/** | |
* Called after a password change was done through webchannel. | |
* | |
* @param {string} sessionToken | |
*/ | |
async handleSessionTokenChange(sessionToken) { | |
// Hep | |
} | |
/** | |
* @returns {Promise<string>} | |
*/ | |
async getTokenServerEndpointURL() { | |
return "https://mozilla.org"; | |
} | |
/** | |
* @returns {Promise<string>} | |
*/ | |
async getPairingAuthorityURL() { | |
return "https://mozilla.org"; | |
} | |
/** | |
* @returns {Promise<string>} | |
*/ | |
async getConnectionSuccessURL() { | |
return "https://mozilla.org"; | |
} | |
/** | |
* @returns {Promise<string>} | |
*/ | |
async getManageAccountURL() { | |
return "https://mozilla.org"; | |
} | |
/** | |
* @returns {Promise<string>} | |
*/ | |
async getManageDevicesURL() { | |
return "https://mozilla.org"; | |
} | |
/** | |
* Fetch the devices in the account. | |
* | |
* @typedef {Object} Device | |
* @property {string} id | |
* @property {string} displayName | |
* @property {DeviceType} deviceType | |
* @property {boolean} isCurrentDevice | |
* @property {Number} [lastAccessTime] | |
* @property {[DeviceCapability]} capabilities | |
* @property {boolean} subscriptionExpired | |
* @property {DevicePushSubscription} [subscription] | |
* | |
* @typedef {Object} DevicePushSubscription | |
* @property {string} endpoint | |
* @property {string} publicKey | |
* @property {string} authKey | |
* | |
* @returns {Promise<[Device]>} | |
*/ | |
async fetchDevices() { | |
return [{ | |
id: "foo", | |
displayName: "Ed's device", | |
deviceType: DeviceType.desktop, | |
isCurrentDevice: false, | |
lastAccessTime: null, | |
capabilities: [DeviceCapability.sendTab], | |
subscriptionExpired: false, | |
subscription: { | |
endpoint: "https://foo.bar", | |
publicKey: "abcde", | |
publicKey: "authKey", | |
} | |
}] | |
} | |
/** | |
* Rename the local device | |
* | |
* @param {string} name | |
*/ | |
async setDeviceDisplayName(name) { | |
// Yay | |
} | |
/** | |
* Handle an incoming Push message payload. | |
* | |
* @typedef {Object} DeviceConnectedEvent | |
* @property {string} deviceName | |
* | |
* @typedef {Object} DeviceDisconnectedEvent | |
* @property {string} deviceId | |
* @property {boolean} isLocalDevice | |
* | |
* @param {string} payload | |
* @return {Promise<[TabReceivedCommand|DeviceConnectedEvent|DeviceDisconnectedEvent]>} | |
*/ | |
async handlePushMessage(payload) { | |
// TODO implement mock. Need to figure out how callers | |
// will tell which case is which. Maybe add a "type" prop? | |
} | |
/** | |
* Fetch for device commands we didn't receive through Push. | |
* | |
* @typedef {Object} TabReceivedCommand | |
* @property {Device} [from] | |
* @property {TabData} tabData | |
* | |
* @typedef {Object} TabData | |
* @property {string} title | |
* @property {string} url | |
* | |
* @returns {Promise<[TabReceivedCommand]>} | |
*/ | |
async pollDeviceCommands() { | |
return [{ | |
from: null, // go lazy here | |
tabData: { | |
title: "Bobotron.com", | |
url: "https://mozilla.org", | |
} | |
}] | |
} | |
/** | |
* Send a tab to a device identified by its ID. | |
* | |
* @param {string} targetId | |
* @param {string} title | |
* @param {string} url | |
*/ | |
async sendSingleTab(targetId, title, url) { | |
// Woo | |
} | |
/** | |
* Update our FxA push subscription. | |
* | |
* @param {string} endpoint | |
* @param {string} publicKey | |
* @param {string} authKey | |
*/ | |
async setDevicePushSubscription(endpoint, publicKey, authKey) { | |
} | |
/** | |
* Initialize the local device (should be done only once after log-in). | |
* | |
* @param {string} name | |
* @param {DeviceType} deviceType | |
* @param {[DeviceCapability]} supportedCapabilities | |
*/ | |
async initializeDevice(name, deviceType, supportedCapabilities) { | |
} | |
/** | |
* Update the device capabilities if needed. | |
* | |
* @param {[DeviceCapability]} supportedCapabilities | |
*/ | |
async ensureCapabilities(supportedCapabilities) { | |
} | |
} | |
/** | |
* @enum | |
*/ | |
const DeviceType = { | |
desktop: Symbol("desktop"), | |
mobile: Symbol("mobile"), | |
tablet: Symbol("tablet"), | |
tv: Symbol("tv"), | |
vr: Symbol("vr"), | |
unknown: Symbol("unknown") | |
}; | |
/** | |
* @enum | |
*/ | |
const DeviceCapability = { | |
sendTab: Symbol("sendTab") | |
}; |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment