Skip to content

Instantly share code, notes, and snippets.

Embed
What would you like to do?
// ==UserScript==
// @name Titech Portal Auto Login
// @namespace http://d.hatena.ne.jp/eagletmt/
// @description 東工大ポータルに自動的にログインします
// @author eagletmt <eagletmt@gmail.com>
// @include https://portal.nap.gsic.titech.ac.jp/GetAccess/Login*
// @match https://portal.nap.gsic.titech.ac.jp/GetAccess/Login*
// @license MIT License
// ==/UserScript==
// original author: NAKASHIMA, Makoto <makoto.nksm@gmail.com>
(function() {
// Configure {{{
const MATRIX_WIDTH = 10;
const MATRIX_HEIGHT = 7;
const NAME_PREFIX = "GM_titech_portal_auto_login_";
const TABLE_ID = NAME_PREFIX + "table_id";
const CELL_ID_PREFIX = NAME_PREFIX + "cell"; //}}}
var X = (function() {//{{{
const KEY = 'matrix_code';
const DEFAULT_CODE = (function() {
var ary = new Array(MATRIX_HEIGHT);
for (var i = 0; i < ary.length; i++) {
ary[i] = new Array(MATRIX_WIDTH);
for (var j = 0; j < ary[i].length; j++) {
ary[i][j] = '_';
}
}
return JSON.stringify(ary);
})();
if (typeof chrome === 'object' && typeof chrome.extension === 'object') {
// Chrome Extension
return {
restoreMatrixCode: function() {
return JSON.parse(localStorage[KEY] || DEFAULT_CODE);
},
saveMatrixCode: function(value) {
localStorage[KEY] = JSON.stringify(value);
},
};
} else if (typeof GM_getValue === 'function') {
// Firefox Greasemonkey
return {
restoreMatrixCode: function() {
return JSON.parse(GM_getValue(KEY, DEFAULT_CODE));
},
saveMatrixCode: function(value) {
GM_setValue(KEY, JSON.stringify(value));
},
};
} else {
console.log('not supported');
return;
}
})();//}}}
if (location.search.indexOf('Template=userpass_key') !== -1) {
main(false);
} else if (document.querySelectorAll('input[type="password"]').length === 3) {
main(true);
} else if (document.querySelector('input[type="submit"][name="OK"]')) {
// login failed?
main(false);
} else {
return;
}
function main(isMatrixPage) {//{{{
var form = document.createElement('form');
form.name = 'matrix';
document.forms[0].parentNode.insertBefore(form, document.forms[0]);
const MSG = 'マトリクスコードを登録';
var submit = document.createElement('input');
form.appendChild(submit);
submit.type = 'submit';
submit.value = MSG;
submit.name = 'OK';
form.addEventListener('submit', function(evt) {
evt.preventDefault();
var table = document.getElementById(TABLE_ID);
if (table.style.display === 'none') {
submit.value = 'マトリクスコードの登録を終了';
table.style.display = '';
} else {
table.style.display = 'none';
submit.value = MSG;
if (isMatrixPage) {
autoLogin();
}
}
}, false);
form.appendChild(createTable());
GM_addStyle(
[
'#TABLE_ID { margin: 0.5em; }',
'#TABLE_ID input, #TABLE_ID table { font-size: 100%; }',
'#TABLE_ID table td { padding: 0; }',
'#TABLE_ID input {',
'width: 1.5em; height: 1.5em; border: none;',
'text-align: center; font-family: inherit;',
'background-color: transparent;',
'}',
'#TABLE_ID input:focus { outline: 2px solid #3d80df; }',
'#TABLE_ID input.error { outline: 2px solid red; }',
].join('').replace(/TABLE_ID/g, TABLE_ID)
);
if (isMatrixPage) {
autoLogin();
}
}//}}}
function createTable() {//{{{
const MATRIX_COL_LABELS = 'ABCDEFGHIJ'.split('');
var table = document.createElement('table');
table.id = TABLE_ID;
table.style.display = 'none';
var tbody = document.createElement('tbody');
table.appendChild(tbody);
var th = table.createTHead();
var tr = th.insertRow(0);
tr.insertCell(0);
MATRIX_COL_LABELS.forEach(function(l) {
var td = tr.insertCell(tr.cells.length);
td.textContent = l;
});
var matrixcode = X.restoreMatrixCode();
for (var i = 0; i < MATRIX_HEIGHT; i++) {
var tr = tbody.insertRow(i);
var th = document.createElement('th');
tr.appendChild(th);
th.textContent = i+1;
if (i % 2 === 0) {
tr.style.backgroundColor = '#ffe8e8';
}
for (var j = 0; j < MATRIX_COL_LABELS.length; j++) {
var cell = tr.insertCell(tr.cells.length);
var input = document.createElement('input');
cell.appendChild(input);
input.id = CELL_ID_PREFIX + i + '_' + j;
input.maxLength = 1;
input.value = matrixcode[i][j];
input.addEventListener('keyup', onKeyUp, false);
input.addEventListener('change', onChange, false);
}
}
return table;
}//}}}
function onKeyUp(evt) {//{{{
var input = evt.target;
if (input.value.length === 1 && String.fromCharCode(evt.keyCode) === input.value) {
var m = input.id.match(/(\d+)_(\d+)$/);
var i = parseInt(m[1]);
var j = parseInt(m[2]);
++j;
if (j === MATRIX_WIDTH) {
i++;
j = 0;
}
if (i !== MATRIX_HEIGHT) {
document.getElementById(CELL_ID_PREFIX + i + '_' + j).select();
} else {
input.blur();
}
}
}//}}}
function onChange(evt) {//{{{
var input = evt.target;
input.value = input.value.toUpperCase();
if (!/^[A-Z]$/.test(input.value)) {
input.classList.add('error');
} else {
input.classList.remove('error');
var ary = new Array(MATRIX_HEIGHT);
for (var i = 0; i < ary.length; i++) {
ary[i] = new Array(MATRIX_WIDTH);
for (var j = 0; j < ary[i].length; j++) {
ary[i][j] = document.getElementById(CELL_ID_PREFIX + i + '_' + j).value;
}
}
X.saveMatrixCode(ary);
}
}//}}}
function autoLogin() {//{{{
var inputCount = 0;
Array.prototype.forEach.call(document.querySelectorAll('input[type="password"]'), function(input) {
var key = input.parentNode.parentNode.textContent;
if (/\[([A-J]),([1-7])\]/.test(key)) {
var col = RegExp.$1.charCodeAt(0) - 'A'.charCodeAt(0);
var row = RegExp.$2 - 1;
var code = X.restoreMatrixCode()[row][col];
if (/^[A-Z]$/.test(code)) {
input.value = code;
inputCount++;
}
}
});
if (inputCount === 3) {
document.querySelector('form[name="login"]').submit();
}
}//}}}
})();
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
You can’t perform that action at this time.