/** * Copyright 2009 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("sqlbase.sqlobj"); import("fastJSON"); import("stringutils"); import("jsutils.eachProperty"); import("sync"); import("etherpad.sessions"); import("etherpad.pro.pro_utils"); import("etherpad.pro.pro_accounts"); import("etherpad.pro.pro_accounts.getSessionProAccount"); import("etherpad.pro.domains"); import("stringutils.randomHash"); var _table = cachedSqlTable('pad_guests', 'pad_guests', ['id', 'privateKey', 'userId'], processGuestRow); function processGuestRow(row) { row.data = fastJSON.parse(row.data); } function notifySignIn() { /*if (pro_accounts.isAccountSignedIn()) { var proId = getUserId(); var guestId = _getGuestUserId(); var guestUser = _getGuestByKey('userId', guestId); if (guestUser) { var mods = {}; mods.data = guestUser.data; // associate guest with proId mods.data.replacement = proId; // de-associate ET cookie with guest, otherwise // the ET cookie would provide a semi-permanent way // to effect changes under the pro account's name! mods.privateKey = "replaced$"+_randomString(20); _updateGuest('userId', guestId, mods); } }*/ } function notifyActive() { if (isGuest(getUserId())) { _updateGuest('userId', getUserId(), {}); } } function notifyUserData(userData) { var uid = getUserId(); if (isGuest(uid)) { var data = _getGuestByKey('userId', uid).data; if (userData.name) { data.name = userData.name; } _updateGuest('userId', uid, {data: data}); } } function getUserId() { if (pro_accounts.isAccountSignedIn()) { return "p."+(getSessionProAccount().id); } else { return getGuestUserId(); } } function getUserName() { var uid = getUserId(); if (isGuest(uid)) { var fromSession = sessions.getSession().guestDisplayName; return fromSession || _getGuestByKey('userId', uid).data.name || null; } else { return getSessionProAccount().fullName; } } function getAccountIdForProAuthor(uid) { if (uid.indexOf("p.") == 0) { return Number(uid.substring(2)); } else { return -1; } } function getNameForUserId(uid) { if (isGuest(uid)) { return _getGuestByKey('userId', uid).data.name || null; } else { var accountNum = getAccountIdForProAuthor(uid); if (accountNum < 0) { return null; } else { return pro_accounts.getAccountById(accountNum).fullName; } } } function isGuest(userId) { return /^g/.test(userId); } function getGuestUserId() { // cache the userId in the requestCache, // for efficiency and consistency var c = appjet.requestCache; if (c.padGuestUserId === undefined) { c.padGuestUserId = _computeGuestUserId(); } return c.padGuestUserId; } function _getGuestTrackerId() { // get ET cookie var tid = sessions.getTrackingId(); if (tid == '-') { // no tracking cookie? not a normal request? return null; } // get domain ID var domain = "-"; if (pro_utils.isProDomainRequest()) { // e.g. "3" domain = String(domains.getRequestDomainId()); } // combine them return domain+"$"+tid; } function _insertGuest(obj) { // only requires 'userId' in obj obj.createdDate = new Date; obj.lastActiveDate = new Date; if (! obj.data) { obj.data = {}; } if ((typeof obj.data) == "object") { obj.data = fastJSON.stringify(obj.data); } if (! obj.privateKey) { // private keys must be unique obj.privateKey = "notracker$"+_randomString(20); } return _table.insert(obj); } function _getGuestByKey(keyColumn, value) { return _table.getByKey(keyColumn, value); } function _updateGuest(keyColumn, value, obj) { var obj2 = {}; eachProperty(obj, function(k,v) { if (k == "data" && (typeof v) == "object") { obj2.data = fastJSON.stringify(v); } else { obj2[k] = v; } }); obj2.lastActiveDate = new Date; _table.updateByKey(keyColumn, value, obj2); } function _newGuestUserId() { return "g."+_randomString(16); } function _computeGuestUserId() { // always returns some userId var privateKey = _getGuestTrackerId(); if (! privateKey) { // no tracking cookie, pretend there is one privateKey = randomHash(16); } var userFromTracker = _table.getByKey('privateKey', privateKey); if (userFromTracker) { // we know this guy return userFromTracker.userId; } // generate userId var userId = _newGuestUserId(); var guest = {userId:userId, privateKey:privateKey}; var data = {}; guest.data = data; var prefsCookieData = _getPrefsCookieData(); if (prefsCookieData) { // found an old prefs cookie with an old userId var oldUserId = prefsCookieData.userId; // take the name and preferences if ('name' in prefsCookieData) { data.name = prefsCookieData.name; } /*['fullWidth','viewZoom'].forEach(function(pref) { if (pref in prefsCookieData) { data.prefs[pref] = prefsCookieData[pref]; } });*/ } _insertGuest(guest); return userId; } function _getPrefsCookieData() { // get userId from old prefs cookie if possible, // but don't allow modern usernames var prefsCookie = request.cookies['prefs']; if (! prefsCookie) { return null; } if (prefsCookie.charAt(0) != '%') { return null; } try { var cookieData = fastJSON.parse(unescape(prefsCookie)); // require one to three digits followed by dot at beginning of userId if (/^[0-9]{1,3}\./.test(String(cookieData.userId))) { return cookieData; } } catch (e) { return null; } return null; } function _randomString(len) { // use only numbers and lowercase letters var pieces = []; for(var i=0;i