remove skip_auth

This commit is contained in:
Tienson Qin
2025-12-30 20:54:40 +08:00
parent 918dc0766a
commit f9a3fb50b9
4 changed files with 191 additions and 163 deletions

View File

@@ -33,37 +33,34 @@
(js-await [auth-header (.get (.-headers request) "authorization") (js-await [auth-header (.get (.-headers request) "authorization")
token (when (and auth-header (string/starts-with? auth-header "Bearer ")) token (when (and auth-header (string/starts-with? auth-header "Bearer "))
(subs auth-header 7)) (subs auth-header 7))
dev-skip? (= "true" (aget env "DEV_SKIP_AUTH"))
claims (cond claims (cond
dev-skip? #js {:sub "dev"}
(nil? token) nil (nil? token) nil
:else (publish-common/verify-jwt token env))] :else (publish-common/verify-jwt token env))]
(let [claims (if dev-skip? #js {:sub "dev"} claims)] (if (nil? claims)
(if (and (not dev-skip?) (nil? claims)) (publish-common/unauthorized)
(publish-common/unauthorized) (let [meta (parse-asset-meta-header request)
(let [meta (parse-asset-meta-header request) graph-uuid (get meta :graph)
graph-uuid (get meta :graph) asset-uuid (get meta :asset_uuid)
asset-uuid (get meta :asset_uuid) asset-type (get meta :asset_type)
asset-type (get meta :asset_type) checksum (get meta :checksum)]
checksum (get meta :checksum)] (if (or (nil? meta) (string/blank? graph-uuid) (string/blank? asset-uuid) (string/blank? asset-type))
(if (or (nil? meta) (string/blank? graph-uuid) (string/blank? asset-uuid) (string/blank? asset-type)) (publish-common/bad-request "missing asset metadata")
(publish-common/bad-request "missing asset metadata") (js-await [body (.arrayBuffer request)
(js-await [body (.arrayBuffer request) r2 (aget env "PUBLISH_R2")
r2 (aget env "PUBLISH_R2") r2-key (str "publish/assets/" graph-uuid "/" asset-uuid "." asset-type)
r2-key (str "publish/assets/" graph-uuid "/" asset-uuid "." asset-type) ^js existing (.head r2 r2-key)
^js existing (.head r2 r2-key) existing-checksum (when existing
existing-checksum (when existing (when-let [meta (.-customMetadata existing)]
(when-let [meta (.-customMetadata existing)] (aget meta "checksum")))
(aget meta "checksum"))) content-type (or (get meta :content_type)
content-type (or (get meta :content_type) (asset-content-type asset-type))
(asset-content-type asset-type)) put? (not (and existing-checksum checksum (= existing-checksum checksum)))
put? (not (and existing-checksum checksum (= existing-checksum checksum))) _ (when put?
_ (when put? (.put r2 r2-key body
(.put r2 r2-key body #js {:httpMetadata #js {:contentType content-type}
#js {:httpMetadata #js {:contentType content-type} :customMetadata #js {:checksum (or checksum "")
:customMetadata #js {:checksum (or checksum "") :owner_sub (aget claims "sub")}}))]
:owner_sub (aget claims "sub")}}))] (publish-common/json-response {:asset_uuid asset-uuid
(publish-common/json-response {:asset_uuid asset-uuid :graph_uuid graph-uuid
:graph_uuid graph-uuid :asset_type asset-type
:asset_type asset-type :asset_url (str "/asset/" graph-uuid "/" asset-uuid "." asset-type)})))))))
:asset_url (str "/asset/" graph-uuid "/" asset-uuid "." asset-type)}))))))))

View File

@@ -49,6 +49,9 @@
(defn unauthorized [] (defn unauthorized []
(json-response {:error "unauthorized"} 401)) (json-response {:error "unauthorized"} 401))
(defn forbidden []
(json-response {:error "forbidden"} 403))
(defn bad-request [message] (defn bad-request [message]
(json-response {:error message} 400)) (json-response {:error message} 400))

View File

@@ -43,110 +43,117 @@
{:allowed? (= hashed stored-hash) :provided? true}) {:allowed? (= hashed stored-hash) :provided? true})
{:allowed? false :provided? false}))))) {:allowed? false :provided? false})))))
(defn- auth-claims
[request env]
(js-await [auth-header (.get (.-headers request) "authorization")
token (when (and auth-header (string/starts-with? auth-header "Bearer "))
(subs auth-header 7))
claims (cond
(nil? token) nil
:else (publish-common/verify-jwt token env))]
{:claims claims}))
(defn handle-post-pages [request env] (defn handle-post-pages [request env]
(js-await [auth-header (.get (.-headers request) "authorization") (js-await [auth-header (.get (.-headers request) "authorization")
token (when (and auth-header (string/starts-with? auth-header "Bearer ")) token (when (and auth-header (string/starts-with? auth-header "Bearer "))
(subs auth-header 7)) (subs auth-header 7))
dev-skip? (= "true" (aget env "DEV_SKIP_AUTH"))
claims (cond claims (cond
dev-skip? #js {:sub "dev"}
(nil? token) nil (nil? token) nil
:else (publish-common/verify-jwt token env))] :else (publish-common/verify-jwt token env))]
(let [claims (if dev-skip? #js {:sub "dev"} claims)] (if (nil? claims)
(if (and (not dev-skip?) (nil? claims)) (publish-common/unauthorized)
(publish-common/unauthorized) (js-await [body (.arrayBuffer request)]
(js-await [body (.arrayBuffer request)] (let [{:keys [content_hash content_length graph page_uuid schema_version block_count created_at] :as meta}
(let [{:keys [content_hash content_length graph page_uuid schema_version block_count created_at] :as meta} (or (publish-common/parse-meta-header request)
(or (publish-common/parse-meta-header request) (publish-common/meta-from-body body))
(publish-common/meta-from-body body)) payload (publish-common/read-transit-safe (.decode publish-common/text-decoder body))
payload (publish-common/read-transit-safe (.decode publish-common/text-decoder body)) payload-entities (publish-model/datoms->entities (:datoms payload))
payload-entities (publish-model/datoms->entities (:datoms payload)) page-eid (some (fn [[e entity]]
page-eid (some (fn [[e entity]] (when (= (:block/uuid entity) (uuid page_uuid))
(when (= (:block/uuid entity) (uuid page_uuid)) e))
e)) payload-entities)
payload-entities) page-title (or (:page-title payload)
page-title (or (:page-title payload) (get payload "page-title")
(get payload "page-title") (when page-eid
(when page-eid (publish-model/entity->title (get payload-entities page-eid))))
(publish-model/entity->title (get payload-entities page-eid)))) blocks (or (:blocks payload)
blocks (or (:blocks payload) (get payload "blocks"))
(get payload "blocks")) page-password-hash (or (:page-password-hash payload)
page-password-hash (or (:page-password-hash payload) (get payload "page-password-hash"))
(get payload "page-password-hash")) refs (when (and page-eid page-title)
refs (when (and page-eid page-title) (publish-index/page-refs-from-payload payload page-eid page_uuid page-title graph))
(publish-index/page-refs-from-payload payload page-eid page_uuid page-title graph)) tagged-nodes (when (and page-eid page-title)
tagged-nodes (when (and page-eid page-title) (publish-index/page-tagged-nodes-from-payload payload page-eid page_uuid page-title graph))]
(publish-index/page-tagged-nodes-from-payload payload page-eid page_uuid page-title graph))] (cond
(cond (not (publish-common/valid-meta? meta))
(not (publish-common/valid-meta? meta)) (publish-common/bad-request "missing publish metadata")
(publish-common/bad-request "missing publish metadata")
:else :else
(js-await [graph-uuid graph (js-await [graph-uuid graph
r2-key (str "publish/" graph-uuid "/" r2-key (str "publish/" graph-uuid "/"
content_hash ".transit") content_hash ".transit")
r2 (aget env "PUBLISH_R2") r2 (aget env "PUBLISH_R2")
existing (.head r2 r2-key) existing (.head r2 r2-key)
_ (when-not existing _ (when-not existing
(.put r2 r2-key body (.put r2 r2-key body
#js {:httpMetadata #js {:contentType "application/transit+json"}})) #js {:httpMetadata #js {:contentType "application/transit+json"}}))
^js do-ns (aget env "PUBLISH_META_DO") ^js do-ns (aget env "PUBLISH_META_DO")
do-id (.idFromName do-ns do-id (.idFromName do-ns
(str graph-uuid (str graph-uuid
":" ":"
page_uuid)) page_uuid))
do-stub (.get do-ns do-id) do-stub (.get do-ns do-id)
page-tags (or (:page-tags payload) page-tags (or (:page-tags payload)
(get payload "page-tags")) (get payload "page-tags"))
short-id (publish-common/short-id-for-page graph-uuid page_uuid) short-id (publish-common/short-id-for-page graph-uuid page_uuid)
owner-sub (:owner_sub meta) owner-sub (:owner_sub meta)
owner-username (:owner_username meta) owner-username (:owner_username meta)
updated-at (.now js/Date) updated-at (.now js/Date)
_ (when-not (and owner-sub owner-username) _ (when-not (and owner-sub owner-username)
(throw (ex-info "owner sub or username is missing" (throw (ex-info "owner sub or username is missing"
{:owner-sub owner-sub {:owner-sub owner-sub
:owner-username owner-username}))) :owner-username owner-username})))
payload (bean/->js payload (bean/->js
{:page_uuid page_uuid {:page_uuid page_uuid
:page_title page-title :page_title page-title
:page_tags (when page-tags :page_tags (when page-tags
(js/JSON.stringify (clj->js page-tags))) (js/JSON.stringify (clj->js page-tags)))
:password_hash page-password-hash :password_hash page-password-hash
:graph graph-uuid :graph graph-uuid
:schema_version schema_version :schema_version schema_version
:block_count block_count :block_count block_count
:content_hash content_hash :content_hash content_hash
:content_length content_length :content_length content_length
:r2_key r2-key :r2_key r2-key
:owner_sub owner-sub :owner_sub owner-sub
:owner_username owner-username :owner_username owner-username
:created_at created_at :created_at created_at
:updated_at updated-at :updated_at updated-at
:short_id short-id :short_id short-id
:refs refs :refs refs
:tagged_nodes tagged-nodes :tagged_nodes tagged-nodes
:blocks (when (seq blocks) :blocks (when (seq blocks)
(map (fn [block] (map (fn [block]
(assoc block :updated_at updated-at)) (assoc block :updated_at updated-at))
blocks))}) blocks))})
meta-resp (.fetch do-stub "https://publish/pages" meta-resp (.fetch do-stub "https://publish/pages"
#js {:method "POST" #js {:method "POST"
:headers #js {"content-type" "application/json"} :headers #js {"content-type" "application/json"}
:body (js/JSON.stringify payload)})] :body (js/JSON.stringify payload)})]
(if-not (.-ok meta-resp) (if-not (.-ok meta-resp)
(publish-common/json-response {:error "metadata store failed"} 500) (publish-common/json-response {:error "metadata store failed"} 500)
(js-await [index-id (.idFromName do-ns "index") (js-await [index-id (.idFromName do-ns "index")
index-stub (.get do-ns index-id) index-stub (.get do-ns index-id)
_ (.fetch index-stub "https://publish/pages" _ (.fetch index-stub "https://publish/pages"
#js {:method "POST" #js {:method "POST"
:headers #js {"content-type" "application/json"} :headers #js {"content-type" "application/json"}
:body (js/JSON.stringify payload)})] :body (js/JSON.stringify payload)})]
(publish-common/json-response {:page_uuid page_uuid (publish-common/json-response {:page_uuid page_uuid
:graph_uuid graph-uuid :graph_uuid graph-uuid
:r2_key r2-key :r2_key r2-key
:short_id short-id :short_id short-id
:short_url (str "/p/" short-id) :short_url (str "/p/" short-id)
:updated_at (.now js/Date)}))))))))))) :updated_at (.now js/Date)}))))))))))
(defn handle-tag-page-html [graph-uuid tag-uuid env] (defn handle-tag-page-html [graph-uuid tag-uuid env]
(if (or (nil? graph-uuid) (nil? tag-uuid)) (if (or (nil? graph-uuid) (nil? tag-uuid))
@@ -436,18 +443,31 @@
page-uuid (nth parts 3 nil)] page-uuid (nth parts 3 nil)]
(if (or (nil? graph-uuid) (nil? page-uuid)) (if (or (nil? graph-uuid) (nil? page-uuid))
(publish-common/bad-request "missing graph uuid or page uuid") (publish-common/bad-request "missing graph uuid or page uuid")
(js-await [^js do-ns (aget env "PUBLISH_META_DO") (js-await [{:keys [claims]} (auth-claims request env)]
page-id (.idFromName do-ns (str graph-uuid ":" page-uuid)) (if (nil? claims)
page-stub (.get do-ns page-id) (publish-common/unauthorized)
index-id (.idFromName do-ns "index") (js-await [^js do-ns (aget env "PUBLISH_META_DO")
index-stub (.get do-ns index-id) page-id (.idFromName do-ns (str graph-uuid ":" page-uuid))
page-resp (.fetch page-stub (str "https://publish/pages/" graph-uuid "/" page-uuid) page-stub (.get do-ns page-id)
#js {:method "DELETE"}) index-id (.idFromName do-ns "index")
index-resp (.fetch index-stub (str "https://publish/pages/" graph-uuid "/" page-uuid) index-stub (.get do-ns index-id)
#js {:method "DELETE"})] meta-resp (.fetch index-stub (str "https://publish/pages/" graph-uuid "/" page-uuid)
(if (or (not (.-ok page-resp)) (not (.-ok index-resp))) #js {:method "GET"})]
(publish-common/not-found) (if-not (.-ok meta-resp)
(publish-common/json-response {:ok true} 200)))))) (publish-common/not-found)
(js-await [meta (.json meta-resp)
owner-sub (aget meta "owner_sub")
subject (aget claims "sub")]
(if (and (or (string/blank? owner-sub)
(not= owner-sub subject)))
(publish-common/forbidden)
(js-await [page-resp (.fetch page-stub (str "https://publish/pages/" graph-uuid "/" page-uuid)
#js {:method "DELETE"})
index-resp (.fetch index-stub (str "https://publish/pages/" graph-uuid "/" page-uuid)
#js {:method "DELETE"})]
(if (or (not (.-ok page-resp)) (not (.-ok index-resp)))
(publish-common/not-found)
(publish-common/json-response {:ok true} 200))))))))))))
(defn handle-delete-graph [request env] (defn handle-delete-graph [request env]
(let [url (js/URL. (.-url request)) (let [url (js/URL. (.-url request))
@@ -455,28 +475,39 @@
graph-uuid (nth parts 2 nil)] graph-uuid (nth parts 2 nil)]
(if-not graph-uuid (if-not graph-uuid
(publish-common/bad-request "missing graph uuid") (publish-common/bad-request "missing graph uuid")
(js-await [^js do-ns (aget env "PUBLISH_META_DO") (js-await [{:keys [claims]} (auth-claims request env)]
index-id (.idFromName do-ns "index") (if (nil? claims)
index-stub (.get do-ns index-id) (publish-common/unauthorized)
list-resp (.fetch index-stub (str "https://publish/pages/" graph-uuid) (js-await [^js do-ns (aget env "PUBLISH_META_DO")
#js {:method "GET"})] index-id (.idFromName do-ns "index")
(if-not (.-ok list-resp) index-stub (.get do-ns index-id)
(publish-common/not-found) list-resp (.fetch index-stub (str "https://publish/pages/" graph-uuid)
(js-await [data (.json list-resp) #js {:method "GET"})]
pages (or (aget data "pages") #js []) (if-not (.-ok list-resp)
_ (js/Promise.all
(map (fn [page]
(let [page-uuid (aget page "page_uuid")
page-id (.idFromName do-ns (str graph-uuid ":" page-uuid))
page-stub (.get do-ns page-id)]
(.fetch page-stub (str "https://publish/pages/" graph-uuid "/" page-uuid)
#js {:method "DELETE"})))
pages))
del-resp (.fetch index-stub (str "https://publish/pages/" graph-uuid)
#js {:method "DELETE"})]
(if-not (.-ok del-resp)
(publish-common/not-found) (publish-common/not-found)
(publish-common/json-response {:ok true} 200)))))))) (js-await [data (.json list-resp)
pages (or (aget data "pages") #js [])
subject (aget claims "sub")
owner-mismatch? (some (fn [page]
(let [owner-sub (aget page "owner_sub")]
(or (string/blank? owner-sub)
(not= owner-sub subject))))
(array-seq pages))]
(if owner-mismatch?
(publish-common/forbidden)
(js-await [_ (js/Promise.all
(map (fn [page]
(let [page-uuid (aget page "page_uuid")
page-id (.idFromName do-ns (str graph-uuid ":" page-uuid))
page-stub (.get do-ns page-id)]
(.fetch page-stub (str "https://publish/pages/" graph-uuid "/" page-uuid)
#js {:method "DELETE"})))
pages))
del-resp (.fetch index-stub (str "https://publish/pages/" graph-uuid)
#js {:method "DELETE"})]
(if-not (.-ok del-resp)
(publish-common/not-found)
(publish-common/json-response {:ok true} 200))))))))))))
(defn handle-page-html [request env] (defn handle-page-html [request env]
(let [url (js/URL. (.-url request)) (let [url (js/URL. (.-url request))

View File

@@ -25,7 +25,6 @@ bucket_name = "logseq-publish-dev"
COGNITO_JWKS_URL = "https://cognito-idp.us-east-1.amazonaws.com/us-east-1_dtagLnju8/.well-known/jwks.json" COGNITO_JWKS_URL = "https://cognito-idp.us-east-1.amazonaws.com/us-east-1_dtagLnju8/.well-known/jwks.json"
COGNITO_ISSUER = "https://cognito-idp.us-east-1.amazonaws.com/us-east-1_dtagLnju8" COGNITO_ISSUER = "https://cognito-idp.us-east-1.amazonaws.com/us-east-1_dtagLnju8"
COGNITO_CLIENT_ID = "69cs1lgme7p8kbgld8n5kseii6" COGNITO_CLIENT_ID = "69cs1lgme7p8kbgld8n5kseii6"
DEV_SKIP_AUTH = "true"
[env.staging] [env.staging]
name = "logseq-publish-staging" name = "logseq-publish-staging"
@@ -34,7 +33,6 @@ name = "logseq-publish-staging"
COGNITO_JWKS_URL = "https://cognito-idp.us-east-1.amazonaws.com/us-east-1_dtagLnju8/.well-known/jwks.json" COGNITO_JWKS_URL = "https://cognito-idp.us-east-1.amazonaws.com/us-east-1_dtagLnju8/.well-known/jwks.json"
COGNITO_ISSUER = "https://cognito-idp.us-east-1.amazonaws.com/us-east-1_dtagLnju8" COGNITO_ISSUER = "https://cognito-idp.us-east-1.amazonaws.com/us-east-1_dtagLnju8"
COGNITO_CLIENT_ID = "69cs1lgme7p8kbgld8n5kseii6" COGNITO_CLIENT_ID = "69cs1lgme7p8kbgld8n5kseii6"
DEV_SKIP_AUTH = "false"
[[env.staging.durable_objects.bindings]] [[env.staging.durable_objects.bindings]]
name = "PUBLISH_META_DO" name = "PUBLISH_META_DO"
@@ -55,7 +53,6 @@ name = "logseq-publish-prod"
COGNITO_JWKS_URL = "https://cognito-idp.us-east-1.amazonaws.com/us-east-1_dtagLnju8/.well-known/jwks.json" COGNITO_JWKS_URL = "https://cognito-idp.us-east-1.amazonaws.com/us-east-1_dtagLnju8/.well-known/jwks.json"
COGNITO_ISSUER = "https://cognito-idp.us-east-1.amazonaws.com/us-east-1_dtagLnju8" COGNITO_ISSUER = "https://cognito-idp.us-east-1.amazonaws.com/us-east-1_dtagLnju8"
COGNITO_CLIENT_ID = "69cs1lgme7p8kbgld8n5kseii6" COGNITO_CLIENT_ID = "69cs1lgme7p8kbgld8n5kseii6"
DEV_SKIP_AUTH = "false"
[[env.prod.durable_objects.bindings]] [[env.prod.durable_objects.bindings]]
name = "PUBLISH_META_DO" name = "PUBLISH_META_DO"