Added support for new login/token endpoints.
This commit is contained in:
parent
4acdf6090f
commit
db20f087b1
6 changed files with 124 additions and 81 deletions
37
src/ami.js/auth.js
Normal file
37
src/ami.js/auth.js
Normal file
|
@ -0,0 +1,37 @@
|
|||
#include commitment.js
|
||||
|
||||
const AmiIsAuth = value => {
|
||||
return typeof value === 'object'
|
||||
&& value !== null
|
||||
&& 'type' in value
|
||||
&& (value.type === null || typeof value.type === 'string')
|
||||
&& 'token' in value
|
||||
&& (value.token === null || typeof value.token === 'string')
|
||||
&& 'header' in value
|
||||
&& (value.header === null || typeof value.header === 'string')
|
||||
&& 'refresh' in value
|
||||
&& typeof value.refresh === 'function';
|
||||
};
|
||||
|
||||
const AmiFlashiiAuth = function(flashii) {
|
||||
let type = null;
|
||||
let token = null;
|
||||
|
||||
return {
|
||||
get type() { return type; },
|
||||
get token() { return token; },
|
||||
get header() { return type ? `${type} ${token}` : null; },
|
||||
|
||||
refresh() {
|
||||
return new Commitment(success => {
|
||||
flashii.v1.chat.token({})
|
||||
.success(result => {
|
||||
({ token_type: type=null, access_token: token=null } = result);
|
||||
success();
|
||||
})
|
||||
.fail(() => { flashii.v1.chat.login({}).run(); })
|
||||
.run();
|
||||
});
|
||||
},
|
||||
};
|
||||
};
|
|
@ -1,8 +1,8 @@
|
|||
#include auth.js
|
||||
#include chat.js
|
||||
#include cookies.js
|
||||
#include copyright.jsx
|
||||
#include emotes.jsx
|
||||
#include flashii.js
|
||||
#include messages.jsx
|
||||
#include notify.js
|
||||
#include reconnect.jsx
|
||||
|
@ -14,11 +14,11 @@
|
|||
#include title.jsx
|
||||
#include txtrigs.js
|
||||
|
||||
var AmiContext = function(title, auth, loading) {
|
||||
var pub = {};
|
||||
var AmiContext = function(title, auth, flashii, loading) {
|
||||
if(!AmiIsAuth(auth))
|
||||
throw new Error('auth param is not acceptable');
|
||||
|
||||
const flashii = new Flashii(`${window.FII_URL}/api`);
|
||||
pub.flashii = flashii;
|
||||
var pub = { auth, flashii };
|
||||
|
||||
var settings = new AmiSettings;
|
||||
pub.settings = settings;
|
||||
|
@ -304,10 +304,17 @@ var AmiContext = function(title, auth, loading) {
|
|||
else
|
||||
overlay += '<br/>' + info.baka.until.toLocaleString();
|
||||
}
|
||||
overlay += `<br/><br/><a href="${window.FII_URL}/_sockchat/login?legacy=1">${AmiStrings.getMenuString('back')}</a>`;
|
||||
|
||||
loading.hideIndicator();
|
||||
loading.setTextRaw(overlay);
|
||||
flashii.v1.chat.login({ assign: false })
|
||||
.success(url => {
|
||||
overlay += `<br/><br/><a href="${url}">${AmiStrings.getMenuString('back')}</a>`;
|
||||
})
|
||||
.always(() => {
|
||||
loading.hideIndicator();
|
||||
loading.setTextRaw(overlay);
|
||||
})
|
||||
.run();
|
||||
|
||||
});
|
||||
sockChat.watch('session:term', function(info) {
|
||||
console.log('session:term', info);
|
||||
|
@ -315,11 +322,17 @@ var AmiContext = function(title, auth, loading) {
|
|||
var overlay = AmiStrings.getMenuString(info.baka.type);
|
||||
if(info.baka.until)
|
||||
overlay += '<br/>' + info.baka.until.toLocaleString();
|
||||
overlay += `<br/><br/><a href="${window.FII_URL}/_sockchat/login?legacy=1">${AmiStrings.getMenuString('back')}</a>`;
|
||||
|
||||
if(loading === undefined)
|
||||
loading = new AmiLoadingOverlay(document.body);
|
||||
loading.setTextRaw(overlay);
|
||||
flashii.v1.chat.login({ assign: false })
|
||||
.success(url => {
|
||||
overlay += `<br/><br/><a href="${url}">${AmiStrings.getMenuString('back')}</a>`;
|
||||
})
|
||||
.always(() => {
|
||||
if(loading === undefined)
|
||||
loading = new AmiLoadingOverlay(document.body);
|
||||
loading.setTextRaw(overlay);
|
||||
})
|
||||
.run();
|
||||
});
|
||||
|
||||
sockChat.watch('user:add', function(info) {
|
||||
|
|
|
@ -66,6 +66,7 @@ const Flashii = function(baseUrl) {
|
|||
body=null,
|
||||
headers=null,
|
||||
type='json',
|
||||
authed=false,
|
||||
}) => {
|
||||
return new Commitment((success, fail) => {
|
||||
const url = createUrl(path, fields);
|
||||
|
@ -80,7 +81,7 @@ const Flashii = function(baseUrl) {
|
|||
headers ??= {};
|
||||
if(fresh) headers['Cache-Control'] = 'no-cache';
|
||||
|
||||
const options = { type, headers };
|
||||
const options = { type, headers, authed };
|
||||
|
||||
$xhr.send(method, url, options, body)
|
||||
.success(success)
|
||||
|
@ -93,6 +94,39 @@ const Flashii = function(baseUrl) {
|
|||
|
||||
fii.v1 = {};
|
||||
|
||||
fii.v1.chat = {};
|
||||
fii.v1.chat.login = function({ redirect=null, assign=true }) {
|
||||
return new Commitment(success => {
|
||||
redirect ??= `${location.protocol}//${location.host}`;
|
||||
if(typeof redirect !== 'string')
|
||||
throw new Error('redirect must a string.');
|
||||
|
||||
const url = createUrl('/v1/chat/login');
|
||||
url.setParam('redirect', redirect);
|
||||
|
||||
// intentionally does not call success
|
||||
if(assign)
|
||||
location.assign(url);
|
||||
else
|
||||
success(url);
|
||||
});
|
||||
};
|
||||
fii.v1.chat.token = function() {
|
||||
return new Commitment((success, fail) => {
|
||||
send({ method: 'GET', path: '/v1/chat/token', authed: true, fresh: true })
|
||||
.success(({ status, body }) => {
|
||||
if(status === 403)
|
||||
throw new Error('You must be logged in to use chat.');
|
||||
if(status > 299)
|
||||
throw new Error(`Failed to fetch authorization token with error code ${status}.`);
|
||||
|
||||
success(body);
|
||||
})
|
||||
.fail(fail)
|
||||
.run();
|
||||
});
|
||||
};
|
||||
|
||||
const verifyColourPresetName = name => {
|
||||
if(/^([^A-Za-z0-9\-_]+)$/gu.test(name))
|
||||
throw new Error('name argument is not an acceptable colour preset name.');
|
||||
|
|
|
@ -4,46 +4,38 @@
|
|||
#include array.js
|
||||
#include html.js
|
||||
|
||||
#include auth.js
|
||||
#include common.js
|
||||
#include ctx.js
|
||||
#include flashii.js
|
||||
#include loadoverlay.jsx
|
||||
#include mszauth.js
|
||||
#include ts_chat.jsx
|
||||
|
||||
(function() {
|
||||
var loading = new AmiLoadingOverlay(document.body, true);
|
||||
const loading = new AmiLoadingOverlay(document.body, true);
|
||||
const flashii = new Flashii(`${window.FII_URL}/api`);
|
||||
const auth = new AmiFlashiiAuth(flashii);
|
||||
|
||||
FutamiCommon.load()
|
||||
.success(futami => {
|
||||
window.futami = futami;
|
||||
auth.refresh()
|
||||
.success(() => {
|
||||
setInterval(() => { auth.refresh(); }, 600000);
|
||||
|
||||
var auth = new AmiMisuzuAuth(`${window.FII_URL}/_sockchat/token`);
|
||||
var refreshInfo = function(next) {
|
||||
auth.refresh().success(token => {
|
||||
if(token.ok === false) {
|
||||
location.assign(`${window.FII_URL}/_sockchat/login?legacy=1`);
|
||||
return;
|
||||
}
|
||||
FutamiCommon.load()
|
||||
.success(futami => {
|
||||
window.futami = futami;
|
||||
|
||||
if(typeof next === 'function')
|
||||
next(token.ok);
|
||||
}).run();
|
||||
};
|
||||
const ami = new AmiContext(window.TITLE, auth, flashii, loading);
|
||||
window.ami = ami;
|
||||
|
||||
var ami = new AmiContext(window.TITLE, auth, loading);
|
||||
window.ami = ami;
|
||||
|
||||
setInterval(refreshInfo, 600000);
|
||||
refreshInfo(function() {
|
||||
Chat.Main();
|
||||
|
||||
ami.sockChat.open();
|
||||
window.addEventListener('beforeunload', () => ami.sockChat.close());
|
||||
});
|
||||
})
|
||||
.fail(ex => {
|
||||
console.log(ex);
|
||||
alert('Failed to load environment settings!');
|
||||
Chat.Main();
|
||||
ami.sockChat.open();
|
||||
window.addEventListener('beforeunload', () => ami.sockChat.close());
|
||||
})
|
||||
.fail(ex => {
|
||||
console.log(ex);
|
||||
alert('Failed to load environment settings!');
|
||||
})
|
||||
.run();
|
||||
})
|
||||
.run();
|
||||
})();
|
||||
|
|
|
@ -1,36 +0,0 @@
|
|||
#include commitment.js
|
||||
#include xhr.js
|
||||
|
||||
var AmiMisuzuAuth = function(refreshUrl) {
|
||||
let userId = null;
|
||||
let authMethod = 'Misuzu';
|
||||
let authToken = null;
|
||||
|
||||
return {
|
||||
hasInfo: () => userId !== null && authToken !== null,
|
||||
getUserId: () => userId,
|
||||
getAuthToken: () => authToken,
|
||||
getLine: () => `${authMethod} ${authToken}`,
|
||||
getInfo: () => {
|
||||
return {
|
||||
method: authMethod,
|
||||
token: authToken,
|
||||
};
|
||||
},
|
||||
refresh: function() {
|
||||
return new Commitment((success, fail) => {
|
||||
$xhr.get(refreshUrl, { authed: true, type: 'json' })
|
||||
.success(({ body }) => {
|
||||
if(body.ok) {
|
||||
userId = body.usr.toString();
|
||||
authToken = body.tkn;
|
||||
}
|
||||
|
||||
success(body);
|
||||
})
|
||||
.fail(fail)
|
||||
.run();
|
||||
});
|
||||
},
|
||||
};
|
||||
};
|
|
@ -1,7 +1,11 @@
|
|||
#include auth.js
|
||||
#include servers.js
|
||||
#include watcher.js
|
||||
|
||||
var AmiSockChat = function(auth) {
|
||||
if(!AmiIsAuth(auth))
|
||||
throw new Error('auth param is not acceptable');
|
||||
|
||||
var pub = {},
|
||||
watchers = new AmiWatcherCollection;
|
||||
|
||||
|
@ -470,8 +474,7 @@ var AmiSockChat = function(auth) {
|
|||
watchers.call('msg:clear', pub);
|
||||
watchers.call('chan:clear', pub);
|
||||
|
||||
var authInfo = auth.getInfo();
|
||||
sendAuth([authInfo.method, authInfo.token]);
|
||||
sendAuth([auth.type, auth.token]);
|
||||
};
|
||||
|
||||
var onClose = function(ev) {
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue