Allow connections from Brutaldon to log in.

This commit is contained in:
Andrew Pietila 2023-10-10 23:44:56 -05:00
parent 4bb28d1c00
commit b559465127
8 changed files with 74 additions and 28 deletions

View file

@ -31,7 +31,7 @@ module.exports = {
},
getTokenData: (token) => {
return db.prepare("SELECT application_id, user_id, created_at, revoked FROM oauth_tokens WHERE token = ?").get(token);
return db.prepare("SELECT application_id, user_id, created_at, revoked, scopes, token FROM oauth_tokens WHERE token = ?").get(token);
},
revokeToken: (token) => {
@ -122,11 +122,11 @@ module.exports = {
},
getAccountByToken: (token) => {
return db.prepare("SELECT id, username, email, password_hash, account_tier FROM accounts WHERE id in (SELECT user_id AS id FROM tokens WHERE token = ?)").get(token);
return db.prepare("SELECT id, username, email, password_hash, account_tier FROM accounts WHERE id IN (SELECT user_id FROM oauth_tokens WHERE token = ?)").get(token);
},
getAccountActivityByAccount: (user_id) => {
return db.prepare("SELECT id, object, type, local, uri_id, owner FROM activity_objects WHERE (type = 'https://www.w3.org/ns/activitystreams#Person' OR type = 'https://www.w3.org/ns/activitystreams#Service') AND local = true AND owner in (SELECT username AS owner WHERE id = ?)").get(user_id);
return db.prepare("SELECT id, object, type, local, uri_id, owner FROM activity_objects WHERE (type = 'https://www.w3.org/ns/activitystreams#Person' OR type = 'https://www.w3.org/ns/activitystreams#Service') AND local = true AND owner in (SELECT username FROM accounts WHERE id = ?)").get(user_id);
},
addActivity: (object, type, local, uri_id, owner) => {
@ -142,6 +142,6 @@ module.exports = {
},
storeW3idSecurityKey: (key_uri, publicKey, privateKey, expires) => {
db.prepare("INSERT INTO w3id_security_keys (key_uri, public_key, private_key) VALUES (?, ?, ?)").run(key_uri, publicKey, privateKey, expires);
db.prepare("INSERT INTO w3id_security_keys (key_uri, public_key, private_key, expires) VALUES (?, ?, ?, ?)").run(key_uri, publicKey, privateKey, expires);
},
};

View file

@ -14,34 +14,34 @@ module.exports = {
},
validate_appropriate_scopes: (max_scope, scope_requested) => {
const max_scope_array_temp = max_scope.split(/(\s|\+)+/);
const max_scope_array_temp = max_scope.split(/[\s+]+/);
const max_scope_array = [];
for (const scope in max_scope_array_temp) {
if (scope.match(/[a-zA-Z0-9:]/)) {
if (max_scope_array_temp[scope].match(/[a-zA-Z0-9:]/)) {
max_scope_array.push(max_scope_array_temp[scope]);
if (scope === "read") {
if (max_scope_array_temp[scope] === "read") {
max_scope_array.push("read:accounts", "read:blocks", "read:bookmarks", "read:favorites", "read:filters", "read:follows", "read:lists", "read:mutes", "read:notifications", "read:search", "read:statuses");
}
if (scope === "write") {
if (max_scope_array_temp[scope] === "write") {
max_scope_array.push("write:accounts", "write:blocks", "write:bookmarks", "write:conversations", "write:favourites", "write:filters", "write:follows", "write:lists", "write:media", "write:mutes", "write:notifications", "write:reports", "write:statuses");
}
if (scope === "follow") {
if (max_scope_array_temp[scope] === "follow") {
max_scope_array.push("read:blocks", "write:blocks", "read:follows", "write:follows", "read:mutes", "write:mutes");
}
if (scope === "admin:read") {
if (max_scope_array_temp[scope] === "admin:read") {
max_scope_array.push("admin:read:accounts", "admin:read:reports", "admin:read:domain_allows", "admin:read:domain_blocks", "admin:read:ip_blocks", "admin:read:email_domain_blocks", "admin:read:canonical_email_blocks");
}
if (scope === "admin:write") {
if (max_scope_array_temp[scope] === "admin:write") {
max_scope_array.push("admin:write:accounts", "admin:write:reports", "admin:write:domain_allows", "admin:write:domain_blocks", "admin:write:ip_blocks", "admin:write:email_domain_blocks", "admin:write:canonical_email_blocks");
}
}
}
const scope_requested_array = scope_requested.split(/(\s|\+)+/);
const scope_requested_array = scope_requested.split(/[\s+]+/);
for (const scope in scope_requested_array) {
if (max_scope_array.includes(scope_requested_array[scope])) {

View file

@ -4,7 +4,7 @@ const input_validate = require("../lib/input_validate");
module.exports = {
auth_token: (needs_user, need_scopes) => {
return (req, res, next) => {
const token = databaseHandler.getTokenData(req.header("authentication").split(/\s+/)[1]);
const token = databaseHandler.getTokenData(req.header("authorization").split(/\s+/)[1]);
if (!token) {
res.status(401);
res.json({
@ -26,13 +26,13 @@ module.exports = {
if (needs_user && token.user_id === 0) {
res.status(401);
res.json({
error: "INSUFFICIENT_AUTHENTICATION",
error: "INSUFFICIENT_AUTHORIZATION",
});
res.end();
return;
}
if (!input_validate(token.scopes, need_scopes)) {
if (need_scopes && !input_validate.validate_appropriate_scopes(token.scopes, need_scopes)) {
res.status(401);
res.json({
error: "INSUFFICIENT_SCOPE",

View file

@ -86,9 +86,10 @@ module.exports = {
},
};
}
const last_status = databaseHandler.getLastStatus(account.username);
res.status(200);
res.json({
id: accountActivityRow.id,
id: accountActivity["@id"],
username: account.username,
acct: account.username,
url: accountActivity["https://www.w3.org/ns/activitystreams#url"]["@id"],
@ -103,7 +104,7 @@ module.exports = {
group: accountActivity["@type"] === "https://www.w3.org/ns/activitystreams#Group",
discoverable: accountActivity["http://joinmastodon.org/ns#discoverable"],
created_at: accountActivity["https://www.w3.org/ns/activitystreams#published"]["@value"],
last_status_at: databaseHandler.getLastStatus(account.username).created_at,
last_status_at: last_status ? last_status.created_at : null,
statuses_count: databaseHandler.getStatusCount(account.username).count,
// TODO: Proper followers and following count.
followers_count: -1,

View file

@ -2,7 +2,53 @@ module.exports = {
route: (routeObj) => {
routeObj.get((req, res) => {
res.status(200);
res.json({});
res.json({
uri: req.headers.host,
title: "Brainz Social",
short_description: "",
description: "",
email: "a.pietila@protonmail.com",
version: "4.2.0",
urls: {},
stats: {
user_count: -1,
status_count: -1,
domain_count: -1
},
thumbnail: null,
languages: [
"en"
],
registrations: true,
approval_required: false,
invites_enabled: false,
configuration: {
accounts: {
max_featured_tags: 4,
},
statuses: {
max_characters: 500,
max_media_attachments: 0,
characters_reserved_per_url: 25
},
media_attachments: {
supported_mime_types: [],
image_size_limit: 0,
image_matrix_limit: 0,
video_size_limit: 0,
video_frame_rate_limit: 0,
video_matrix_limit: 0,
},
polls: {
max_options: 0,
max_characters_per_option: 0,
min_expiration: Number.MAX_SAFE_INTEGER,
max_expiration: Number.MAX_SAFE_INTEGER,
},
contact_account: {},
rules: [],
},
});
return;
});
},

View file

@ -14,11 +14,11 @@ module.exports = {
return;
}
if (!req.cookies || !req.cookies.auth) {
const new_redirect_url = new URL("http://example.com");
const new_redirect_url = new URL("https://example.com");
new_redirect_url.host = req.headers.host;
new_redirect_url.pathname = req.path;
new_redirect_url.search = qs.stringify(req.query);
const redirecting_to = new URL("http://example.com");
const redirecting_to = new URL("https://example.com");
redirecting_to.host = req.headers.host;
redirecting_to.pathname = "/login";
redirecting_to.searchParams.set("redirect_to", new_redirect_url.toString());
@ -46,7 +46,7 @@ module.exports = {
}
res.status(200);
res.cookie("auth", new_cookie_value);
const approve_url = new URL("http://example.com");
const approve_url = new URL("https://example.com");
approve_url.host = req.headers.host;
approve_url.pathname = "/oauth/authorize/yes";
approve_url.searchParams.set("response_type", req.query.response_type);
@ -66,11 +66,11 @@ module.exports = {
res.end();
return;
}
const new_redirect_url = new URL("http://example.com");
const new_redirect_url = new URL("https://example.com");
new_redirect_url.host = req.headers.host;
new_redirect_url.pathname = req.path;
new_redirect_url.search = qs.stringify(req.query);
const redirecting_to = new URL("http://example.com");
const redirecting_to = new URL("https://example.com");
redirecting_to.host = req.headers.host;
redirecting_to.pathname = "/login";
redirecting_to.searchParams.set("redirect_to", new_redirect_url.toString());

View file

@ -5,14 +5,14 @@ const databaseHandler = require("../../../lib/database-handler");
module.exports = {
route: (routeObj) => {
routeObj.get((req, res) => {
const request_url = new URL("http://example.com");
const request_url = new URL("https://example.com");
request_url.host = req.headers.host;
request_url.pathname = "/oauth/authorize/yes";
request_url.search = new URLSearchParams(qs.stringify(req.query));
const cookie_object = databaseHandler.checkAuthCookie(req.cookies.auth);
if (cookie_object.revoked || (cookie_object.created_at + 86400) < Math.floor(Date.now() / 1000)) {
res.status(302);
const redirect_to = new URL("http://example.com");
const redirect_to = new URL("https://example.com");
redirect_to.host = req.headers.host;
redirect_to.pathname = "/login";
redirect_to.searchParams.set("redirect_to", request_url.toString());
@ -21,7 +21,7 @@ module.exports = {
}
databaseHandler.revokeAuthCookie(cookie_object.cookie_value);
const new_cookie = crypto.randomBytes(32).toString("base64");
databaseHandler.createAuthCookie(new_cookie, Math.floor(Date.now() / 1000), cookie_object.id);
databaseHandler.createAuthCookie(new_cookie, Math.floor(Date.now() / 1000), cookie_object.user_id);
const csrf_token = databaseHandler.getCsrfToken(request_url.toString());
if (csrf_token.cookie_value === req.cookies.auth && (Math.floor(Date.now() / 1000) < (csrf_token.created_at + 300))) {
const response_code = crypto.randomBytes(32).toString("base64");
@ -50,7 +50,6 @@ module.exports = {
redirect_to.search = qs.stringify(req.query);
res.status(302);
res.redirect(redirect_to.toString());
res.send("<html><body>REDIRECTING</body></html>");
res.end();
return;
});

View file

@ -74,7 +74,7 @@ module.exports = {
res.json({
access_token: token,
token_type: "Bearer",
scope: req.query.scope,
scope: req.body.scope,
created_at,
});
return;