1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188
/*
* Copyright (c) 2015-2017, Michael A. Updike All rights reserved.
* Licensed under the BSD-3-Clause
* https://opensource.org/licenses/BSD-3-Clause
* https://github.com/opus1269/photo-screen-saver/blob/master/LICENSE.md
*/
window.app = window.app || {};
/**
* Handle optional permissions
* @namespace
*/
app.Permissions = (function() {
'use strict';
new ExceptionHandler();
const chromep = new ChromePromise();
/**
* A permission state enum
* @typedef {{}} app.Permissions.State
* @property {string} notSet - never been allowed or denied
* @property {string} allowed - user allowed
* @property {string} denied - user denied
* @memberOf app.Permissions
*/
/**
* A permission type
* @typedef {{}} app.Permissions.Type
* @property {string} name - name in localStorage
* @property {string[]} permissions - array of permissions
* @property {string[]} origins - array of origins
* @memberOf app.Permissions
*/
/**
* Possible states of an {@link app.Permissions.Type}
* @type {app.Permissions.State}
* @const
* @private
* @memberOf app.Permissions
*/
const _STATE = {
notSet: 'notSet',
allowed: 'allowed',
denied: 'denied',
};
/**
* Permission for access to users' Google Photos
* @const
* @type {app.Permissions.Type}
* @memberOf app.Permissions
*/
const PICASA = {
name: 'permPicasa',
permissions: [],
origins: ['https://picasaweb.google.com/'],
};
/**
* Permission for running in background
* @const
* @type {app.Permissions.Type}
* @memberOf app.Permissions
*/
const BACKGROUND = {
name: 'permBackground',
permissions: ['background'],
origins: [],
};
/**
* Persist the state of an {@link app.Permissions.Type}
* @param {app.Permissions.Type} type - permission type
* @param {string} value - permission state
* @private
* @memberOf app.Permissions
*/
function _setState(type, value) {
// send message to store value so items that are bound
// to it will get storage event
const msg = Chrome.JSONUtils.shallowCopy(Chrome.Msg.STORE);
msg.key = type.name;
msg.value = value;
Chrome.Msg.send(msg).catch(() => {});
}
/**
* Determine if we have the optional permissions
* @param {app.Permissions.Type} type - permission type
* @returns {Promise<boolean>} true if we have permissions
* @memberOf app.Permissions
*/
function _contains(type) {
return chromep.permissions.contains({
permissions: type.permissions,
origins: type.origins,
});
}
return {
/**
* @type {app.Permissions.Type}
* @memberOf app.Permissions
*/
PICASA: PICASA,
/**
* @type {app.Permissions.Type}
* @memberOf app.Permissions
*/
BACKGROUND: BACKGROUND,
/**
* Has user made choice on permissions
* @param {app.Permissions.Type} type - permission type
* @returns {boolean} true if allowed or denied
* @memberOf app.Permissions
*/
notSet: function(type) {
return Chrome.Storage.get(type.name) === _STATE.notSet;
},
/**
* Has the user allowed the optional permissions
* @param {app.Permissions.Type} type - permission type
* @returns {boolean} true if allowed
* @memberOf app.Permissions
*/
isAllowed: function(type) {
return Chrome.Storage.get(type.name) === _STATE.allowed;
},
/**
* Request optional permission - may block
* @param {app.Permissions.Type} type - permission type
* @returns {Promise<boolean>} true if permission granted
* @memberOf app.Permissions
*/
request: function(type) {
let isGranted;
return chromep.permissions.request({
permissions: type.permissions,
origins: type.origins,
}).then((granted) => {
isGranted = granted;
if (granted) {
_setState(type, _STATE.allowed);
return Promise.resolve();
} else {
_setState(type, _STATE.denied);
// try to remove if it has been previously granted
return app.Permissions.remove(type);
}
}).then(() => {
return Promise.resolve(isGranted);
});
},
/**
* Remove the optional permissions
* @param {app.Permissions.Type} type - permission type
* @returns {Promise<boolean>} true if removed
* @memberOf app.Permissions
*/
remove: function(type) {
return _contains(type).then((contains) => {
if (contains) {
// try to remove permission
return chromep.permissions.remove({
permissions: type.permissions,
origins: type.origins,
});
} else {
return Promise.resolve(false);
}
}).then((removed) => {
if (removed) {
_setState(type, _STATE.notSet);
}
return Promise.resolve(removed);
});
},
};
})();