diff --git a/components/core/ApplicationHeader.js b/components/core/ApplicationHeader.js index 8a93f69f..d1840c5e 100644 --- a/components/core/ApplicationHeader.js +++ b/components/core/ApplicationHeader.js @@ -163,7 +163,7 @@ export default class ApplicationHeader extends React.Component { style={{ marginLeft: 12 }} onClick={() => {}} size={32} - url={this.props.viewer.photoURL} + url={this.props.viewer.data.photo} popover={ { diff --git a/node_common/data/index.js b/node_common/data/index.js index 289bc09e..0ab788b2 100644 --- a/node_common/data/index.js +++ b/node_common/data/index.js @@ -2,5 +2,12 @@ import createUser from "~/node_common/data/methods/create-user"; import updateUserById from "~/node_common/data/methods/update-user-by-id"; import deleteUserByUsername from "~/node_common/data/methods/delete-user-by-username"; import getUserByUsername from "~/node_common/data/methods/get-user-by-username"; +import getUserById from "~/node_common/data/methods/get-user-by-id"; -export { createUser, updateUserById, deleteUserByUsername, getUserByUsername }; +export { + createUser, + updateUserById, + deleteUserByUsername, + getUserByUsername, + getUserById, +}; diff --git a/node_common/data/methods/get-user-by-id.js b/node_common/data/methods/get-user-by-id.js new file mode 100644 index 00000000..fcc6fc2d --- /dev/null +++ b/node_common/data/methods/get-user-by-id.js @@ -0,0 +1,29 @@ +import { runQuery } from "~/node_common/data/utilities"; + +export default async ({ id }) => { + return await runQuery({ + label: "GET_USER_BY_ID", + queryFn: async (DB) => { + const query = await DB.select("*") + .from("users") + .where({ id }) + .first(); + + if (!query || query.error) { + return null; + } + + if (query.id) { + return query; + } + + return null; + }, + errorFn: async (e) => { + return { + error: "GET_USER_BY_ID", + source: e, + }; + }, + }); +}; diff --git a/node_common/data/methods/update-user-by-id.js b/node_common/data/methods/update-user-by-id.js index 3be80b5d..e6389481 100644 --- a/node_common/data/methods/update-user-by-id.js +++ b/node_common/data/methods/update-user-by-id.js @@ -1,16 +1,22 @@ import { runQuery } from "~/node_common/data/utilities"; -export default async ({ id, data }) => { +export default async ({ id, data, username }) => { + const updateObject = {}; + + if (data) { + updateObject.data = data; + } + + if (username) { + updateObject.username = username; + } + return await runQuery({ label: "UPDATE_USER_BY_ID", queryFn: async (DB) => { const response = await DB.from("users") .where("id", id) - .update({ - data: { - ...data, - }, - }) + .update(updateObject) .returning("*"); const index = response ? response.pop() : null; diff --git a/node_common/middleware.js b/node_common/middleware.js index 1ae45355..a41d9d51 100644 --- a/node_common/middleware.js +++ b/node_common/middleware.js @@ -51,8 +51,8 @@ export const RequireCookieAuthentication = async (req, res, next) => { try { const decoded = JWT.verify(token, Environment.JWT_SECRET); - const user = await Data.getUserByUsername({ - username: decoded.username, + const user = await Data.getUserById({ + id: decoded.id, }); if (!user || user.error) { diff --git a/node_common/models.js b/node_common/models.js index 103aa0fe..35a71049 100644 --- a/node_common/models.js +++ b/node_common/models.js @@ -3,9 +3,9 @@ import * as Data from "~/node_common/data"; import PG from "~/node_common/powergate"; -export const getViewer = async ({ username }) => { - const user = await Data.getUserByUsername({ - username, +export const getViewer = async ({ id }) => { + const user = await Data.getUserById({ + id, }); if (!user) { diff --git a/node_common/utilities.js b/node_common/utilities.js index 595556b9..b0a805e6 100644 --- a/node_common/utilities.js +++ b/node_common/utilities.js @@ -16,8 +16,8 @@ const TEXTILE_KEY_INFO = { secret: Environment.TEXTILE_HUB_SECRET, }; -export const getUserFromCookie = (req) => { - let username; +export const getIdFromCookie = (req) => { + let id; if (!Strings.isEmpty(req.headers.cookie)) { const token = req.headers.cookie.replace( /(?:(?:^|.*;\s*)WEB_SERVICE_SESSION_KEY\s*\=\s*([^;]*).*$)|^.*$/, @@ -27,14 +27,14 @@ export const getUserFromCookie = (req) => { if (!Strings.isEmpty(token)) { try { const decoded = JWT.verify(token, Environment.JWT_SECRET); - username = decoded.username; + id = decoded.id; } catch (e) { console.log(e); } } } - return username; + return id; }; export const parseAuthHeader = (value) => { diff --git a/pages/api/addresses/send.js b/pages/api/addresses/send.js index 5db39dc3..b7674fa2 100644 --- a/pages/api/addresses/send.js +++ b/pages/api/addresses/send.js @@ -11,15 +11,15 @@ export default async (req, res) => { initCORS(req, res); initAuth(req, res); - const username = Utilities.getUserFromCookie(req); - if (!username) { + const id = Utilities.getIdFromCookie(req); + if (!id) { return res .status(500) .json({ decorator: "SERVER_SEND_FILECOIN", error: true }); } - const user = await Data.getUserByUsername({ - username, + const user = await Data.getUserById({ + id, }); if (!user) { diff --git a/pages/api/data/[upload].js b/pages/api/data/[upload].js index 4b060501..2cd20e5d 100644 --- a/pages/api/data/[upload].js +++ b/pages/api/data/[upload].js @@ -45,9 +45,9 @@ export default async (req, res) => { }; // TODO(jim): Send this file to buckets. - const username = Utilities.getUserFromCookie(req); - const user = await Data.getUserByUsername({ - username, + const id = Utilities.getIdFromCookie(req); + const user = await Data.getUserById({ + id, }); const { diff --git a/pages/api/hydrate.js b/pages/api/hydrate.js index ebcea64a..d652aee8 100644 --- a/pages/api/hydrate.js +++ b/pages/api/hydrate.js @@ -9,14 +9,14 @@ export default async (req, res) => { initCORS(req, res); initAuth(req, res); - const username = Utilities.getUserFromCookie(req); - if (!username) { + const id = Utilities.getIdFromCookie(req); + if (!id) { return res .status(500) .json({ decorator: "SERVER_USER_DELETE", error: true }); } - const data = await Models.getViewer({ username }); + const data = await Models.getViewer({ id }); return res .status(200) diff --git a/pages/api/sign-in.js b/pages/api/sign-in.js index b5051bbd..f8830846 100644 --- a/pages/api/sign-in.js +++ b/pages/api/sign-in.js @@ -65,7 +65,7 @@ export default async (req, res) => { } const token = JWT.sign( - { user: user.id, username: user.username }, + { id: user.id, username: user.username }, Environment.JWT_SECRET ); diff --git a/pages/api/users/create.js b/pages/api/users/create.js index 946eb354..1d32cf0c 100644 --- a/pages/api/users/create.js +++ b/pages/api/users/create.js @@ -86,6 +86,6 @@ export default async (req, res) => { return res.status(200).json({ decorator: "SERVER_USER_CREATE", - user: { username: user.username }, + user: { username: user.username, id: user.id }, }); }; diff --git a/pages/api/users/delete.js b/pages/api/users/delete.js index 3cb7d1d9..48e0448d 100644 --- a/pages/api/users/delete.js +++ b/pages/api/users/delete.js @@ -21,15 +21,15 @@ export default async (req, res) => { initCORS(req, res); initAuth(req, res); - const username = Utilities.getUserFromCookie(req); - if (!username) { + const id = Utilities.getIdFromCookie(req); + if (!id) { return res .status(500) .json({ decorator: "SERVER_USER_DELETE", error: true }); } - const user = await Data.getUserByUsername({ - username, + const user = await Data.getUserById({ + id, }); if (!user) { diff --git a/pages/api/users/update.js b/pages/api/users/update.js index 53d0fb98..3ec601c6 100644 --- a/pages/api/users/update.js +++ b/pages/api/users/update.js @@ -13,15 +13,15 @@ export default async (req, res) => { initCORS(req, res); initAuth(req, res); - const username = Utilities.getUserFromCookie(req); - if (!username) { + const id = Utilities.getIdFromCookie(req); + if (!id) { return res .status(500) .json({ decorator: "SERVER_USER_UPDATE", error: true }); } - const user = await Data.getUserByUsername({ - username, + const user = await Data.getUserById({ + id, }); if (!user) { @@ -43,6 +43,19 @@ export default async (req, res) => { }); } + if (req.body.username) { + const existing = await Data.getUserByUsername({ + username: req.body.username, + }); + + if (!existing) { + await Data.updateUserById({ + id: user.id, + username: req.body.username, + }); + } + } + // TODO(jim): POWERGATE_ISSUE 0.2.0 // Should work when our hosted Powergate works. if (req.body.type === "SET_DEFAULT_STORAGE_CONFIG") { diff --git a/pages/application.js b/pages/application.js index 66e39314..5e747eae 100644 --- a/pages/application.js +++ b/pages/application.js @@ -453,6 +453,7 @@ export default class ApplicationPage extends React.Component { onAction: this._handleAction, onBack: this._handleBack, onForward: this._handleForward, + onRehydrate: this.rehydrate, }); let sidebarElement; @@ -465,6 +466,7 @@ export default class ApplicationPage extends React.Component { onSubmit: this._handleSubmit, onCancel: this._handleCancel, onSetFile: this._handleSetFile, + onRehydrate: this.rehydrate, }); } diff --git a/scenes/SceneEditAccount.js b/scenes/SceneEditAccount.js index 6700ce17..3a2c1b77 100644 --- a/scenes/SceneEditAccount.js +++ b/scenes/SceneEditAccount.js @@ -28,9 +28,6 @@ export default class SceneEditAccount extends React.Component { state = { username: this.props.viewer.username, deleting: false }; _handleUpload = async (e) => { - // TODO(jim): - // Rewrite - /* e.persist(); let file = e.target.files[0]; @@ -49,26 +46,22 @@ export default class SceneEditAccount extends React.Component { body: data, }; - await fetch(`/_/upload/avatar`, options); - */ + const response = await fetch(`/api/data/${file.name}`, options); + const json = await response.json(); + + await Actions.updateViewer({ + data: { photo: `https://hub.textile.io${json.data.ipfs}` }, + }); + + this.props.onRehydrate(); }; _handleSave = async (e) => { - // TODO(jim): - // Rewrite - /* - const options = { - method: "POST", - headers: { - Accept: "application/json", - "Content-Type": "application/json", - }, - credentials: "include", - body: JSON.stringify({ local: { name: this.state.name } }), - }; + await Actions.updateViewer({ + username: this.state.username, + }); - await fetch(`/_/local-settings`, options); - */ + this.props.onRehydrate(); }; _handleDelete = async (e) => { @@ -101,7 +94,7 @@ export default class SceneEditAccount extends React.Component {
diff --git a/server.js b/server.js index 6fd0032d..2874d7cc 100644 --- a/server.js +++ b/server.js @@ -26,12 +26,12 @@ app.prepare().then(async () => { server.use("/public", express.static("public")); server.get("/application", async (req, res) => { - const username = Utilities.getUserFromCookie(req); + const id = Utilities.getIdFromCookie(req); let viewer = null; - if (username) { + if (id) { viewer = await Models.getViewer({ - username, + id, }); } @@ -43,12 +43,12 @@ app.prepare().then(async () => { }); server.get("/@:username", async (req, res) => { - const username = Utilities.getUserFromCookie(req); + const id = Utilities.getIdFromCookie(req); let viewer = null; - if (username) { + if (id) { viewer = await Models.getViewer({ - username, + id, }); }