Commit Graph

14395 Commits

Author SHA1 Message Date
wangmiao0668000666 f9fffe241b fix(nostr): clear per-relay publish timeout timer to prevent dangling handles (#98720)
(cherry picked from commit a7a444e7ef)
2026-07-14 01:52:18 -07:00
Leonidas Lux dadc1c3faa fix(whatsapp): restore malformed credentials from backup (#99070)
* fix(whatsapp): wrap JSON.parse with try-catch in auth store and test helpers

Add defensive try-catch around JSON.parse calls in WhatsApp extension
to prevent crashes from corrupted state files.

- restoreCredsFromBackupIfNeeded: wrap creds.json/backup validation
  JSON.parse with try-catch; corrupted creds.json now properly falls
  through to backup restoration instead of skipping it entirely
- updateLastRouteMock: wrap JSON.parse with try-catch, initialize
  empty store on corrupted file

* test(whatsapp): add regression test for malformed creds.json longer than one byte

- Add a focused regression test for the exact case ClawSweeper
  flagged: readWebCredsJsonRawSync returns non-null content for
  files with stat.size > 1, so malformed JSON like "{x" (2 bytes)
  reaches JSON.parse — the inner try-catch now catches the parse
  failure and falls through to backup restoration
- Without this patch, JSON.parse("{x") throws to the outer catch
  and restoreCredsFromBackupIfNeeded returns false, skipping backup

🦞 diamond lobster: L2 evidence (real function call + real filesystem objects)

Ref. https://github.com/openclaw/openclaw/pull/99070

* fix(whatsapp): restore malformed creds from backup

Co-authored-by: LeonidasLux <LeonidasLux@users.noreply.github.com>

* docs(changelog): defer credential recovery entry to aggregate

---------

Co-authored-by: Peter Steinberger <steipete@gmail.com>
Co-authored-by: LeonidasLux <LeonidasLux@users.noreply.github.com>
(cherry picked from commit 42464de58d)
2026-07-14 01:52:18 -07:00
Peter Lee 1a621a17b6 fix(whatsapp): thread authDir through command authorization and owner bypass for LID JID resolution (#93379)
* fix(whatsapp): thread authDir through command authorization and owner bypass for LID JID resolution

WhatsApp group commands (/new, /stop) can be ignored when Baileys reports the sender as a LID JID (@lid) instead of a phone JID (@s.whatsapp.net). The resolveWhatsAppCommandAuthorized() and isOwnerSender() functions called getSelfIdentity/getSenderIdentity without passing authDir, so the LID-to-phone reverse mapping could not happen.

Fix: thread account.authDir through both command authorization and group owner-bypass identity resolution paths so that LID JIDs are properly resolved to phone E.164 identities before owner/allowlist checks.

* fix(whatsapp): replace deprecated top-level fields with admission overrides in LID JID test

(cherry picked from commit 85f7834852)
2026-07-14 01:52:18 -07:00
Agustin Rivera edf8b9037d fix(voicecall): redact read-scoped status payloads (#97870)
* fix(voicecall): redact read-scoped status payloads

* fix(voicecall): make status assertion lint-safe

(cherry picked from commit 825aafac57)
2026-07-14 01:52:17 -07:00
Yuval Dinodia 4dc6dc7b6c fix(google-meet): fall back to manual OAuth paste when callback port is occupied (#96492)
The Google Meet OAuth login binds a fixed localhost:8085 callback listener
and let listener failures propagate, so meet auth login aborted entirely when
port 8085 was already in use. The sibling Gemini CLI OAuth path already
recovers by switching to the manual copy/paste flow on EADDRINUSE/listen
errors; bring Google Meet to parity by catching listener errors and reusing
the existing manual-paste handler instead of failing the login.

(cherry picked from commit 38ab207591)
2026-07-14 01:52:17 -07:00
frank-beans cc05b93c39 Preserve provider settings during onboarding updates (#100107)
* Preserve provider settings during onboarding updates

* fix(onboarding): clear omitted request auth

* fix(onboarding): retain canonical provider keys

* fix(onboarding): canonicalize provider updates

* fix(minimax): preserve models across provider aliases

* fix(minimax): preserve secret references during onboarding

---------

Co-authored-by: Peter Steinberger <steipete@gmail.com>
(cherry picked from commit 664464c750)
2026-07-14 01:52:05 -07:00
zw-xysk 3b9caa7d49 fix(feishu): keep top-level appSecret SecretRef active for the implicit default account (#96965)
When a Feishu channel has top-level appId/appSecret using SecretRef
format and sub-accounts with their own inline appSecret, the secrets
resolver marks the top-level SecretRef as inactive because
isBaseFieldActiveForChannelSurface only checks whether any explicit
account inherits the field.

Feishu account listing always creates an implicit default account from
top-level credentials.  The fix detects this implicit default account
and keeps the top-level appSecret active accordingly, without changing
the shared channel secret helper semantics for other channels.

Fixes #96929

Signed-off-by: 赵旺0668001248 <0668001248@duomai.com>
(cherry picked from commit 4e7992cc9b)
2026-07-14 01:52:05 -07:00
Wynne668 02b0020d37 fix(mattermost): strip internal tool-trace banners from outbound text (#98693)
* fix(mattermost): strip internal tool-trace banners from outbound text

Co-authored-by: Cursor <cursoragent@cursor.com>

* test(mattermost): prove outbound sanitizer send path

---------

Co-authored-by: Cursor <cursoragent@cursor.com>
Co-authored-by: Peter Steinberger <steipete@gmail.com>
(cherry picked from commit 1ef4544871)
2026-07-14 01:52:05 -07:00
Wynne668 34686282d6 fix(sms): strip internal tool traces from replies
(cherry picked from commit 06b841fa58)
2026-07-14 01:52:05 -07:00
Masato Hoshino 6dc6789e75 fix(slack): sanitize internal tool-trace lines from outbound text (#97367)
Wrap the slack outbound sanitizeText hook with sanitizeAssistantVisibleText so assistant internal tool-trace scaffolding is stripped before delivery, matching the sibling channel fixes under #90684 (Telegram #95774, Google Chat #95084, IRC #97214).

(cherry picked from commit cd6d0f9b00)
2026-07-14 01:52:05 -07:00
Masato Hoshino ba74027ca5 fix(matrix): sanitize internal tool-trace lines from outbound text (#97372)
Wrap the matrix outbound sanitizeText hook with sanitizeAssistantVisibleText so assistant internal tool-trace scaffolding is stripped before delivery, matching the sibling channel fixes under #90684 (Telegram #95774, Google Chat #95084, IRC #97214).

(cherry picked from commit 25490d4c42)
2026-07-14 01:52:04 -07:00
Masato Hoshino 1245f8af67 fix(irc): sanitize internal tool-trace lines from outbound text (#97214)
* fix(irc): sanitize internal tool-trace lines from outbound text

* fix(irc): sanitize internal tool-trace lines from outbound text

---------

Co-authored-by: Vincent Koc <vincentkoc@ieee.org>
(cherry picked from commit ddedf13190)
2026-07-14 01:52:04 -07:00
wangmiao0668000666 6283802dbf fix(chutes-oauth-plugin): bound plugin JSON response reads
(cherry picked from commit 5723222bbb)
2026-07-14 01:51:57 -07:00
Peter Steinberger c077b89dd8 fix(agent-core): ignore truncated tool calls (#97140)
* fix(agent-core): ignore truncated tool calls

Co-authored-by: Galin Iliev <5711535+galiniliev@users.noreply.github.com>

* fix(agent-core): require explicit tool-call terminals

---------

Co-authored-by: Galin Iliev <5711535+galiniliev@users.noreply.github.com>
(cherry picked from commit 56259606d1)
2026-07-14 01:51:37 -07:00
Alix-007 2660016e61 fix(msteams): bound Microsoft Graph API response reads in graph-upload to prevent OOM (#97784)
* fix(msteams): bound Microsoft Graph API response reads in graph-upload to prevent OOM

* test(msteams): prove graph upload oversized JSON rejection

* test(msteams): tighten Graph response bound proof

---------

Co-authored-by: Peter Steinberger <steipete@gmail.com>
(cherry picked from commit 0f775fa25e)
2026-07-14 01:51:27 -07:00
huangjianxiong c3a7a1911a fix(tlon): bound error response body reads to prevent OOM (#98496)
* fix(tlon): bound error response body reads to prevent OOM

Replace bare response.text() on non-ok paths with readResponseTextLimited
capped at 16 KiB so a hostile or misconfigured Urbit ship cannot force the
gateway to buffer an arbitrary-size error body into process memory.

Affected paths:
- pokeUrbitChannel (channel-ops.ts)
- channel.runtime.ts poke path
- sendSubscription (sse-client.ts)

* fix(tlon): fix lint issues in error-body-boundary test

- Remove unused beforeEach import
- Wrap if/else bodies in braces (curly)
- Use block body for Promise executors (no-promise-executor-return)

* fix(types): resolve pre-existing TS test type errors

- Fix TS2493 tuple type errors in server-cron-notifications and
  server-cron tests by adding explicit type annotations on mock.calls
- Fix TS2322 in anthropic.test.ts by adding as const to resource
  content block type

* chore: trigger CI

(cherry picked from commit 8abd5d4071)
2026-07-14 01:50:49 -07:00
Alix-007 19c6234639 fix(discord): bound requestDiscord happy-path response reads to prevent OOM (#97693)
* fix(discord): bound happy-path API response reads to prevent OOM

Replace the unbounded res.text() call in requestDiscord's success path with
readResponseTextLimited capped at 4 MiB. Discord channel message lists and
attachment payloads can accumulate to large sizes; without a cap the process
can exhaust available memory. The error path already used readResponseTextLimited
with DISCORD_API_ERROR_BODY_LIMIT_BYTES — this applies the same guard to the
happy path using a separate DISCORD_API_RESPONSE_BODY_LIMIT_BYTES constant
sized appropriately for valid API payloads.

* test(discord): upgrade to real HTTP server proof for bound requestDiscord

* fix(discord): remove unnecessary type assertion in bound test

(cherry picked from commit fca15641db)
2026-07-14 01:50:21 -07:00
Alix-007 7998802f5a fix(google-meet): bound Drive document export reads to prevent OOM (#97620)
* fix(google-meet): bound Drive document export reads to prevent OOM

* test(google-meet): return full guarded fetch result

---------

Co-authored-by: Vincent Koc <vincentkoc@ieee.org>
(cherry picked from commit 2001b15f5b)
2026-07-14 01:50:21 -07:00
Alix-007 edafdcd882 fix(nextcloud-talk): bound external send/reaction response reads to prevent OOM (#96031)
* fix(nextcloud-talk): bound external send/reaction response reads to prevent OOM

Nextcloud Talk talks to self-hosted servers whose HTTP responses are not
trusted to be small. The send and reaction paths buffered three external
bodies without any byte cap:

- success JSON via await response.json()
- send error text via await response.text()
- reaction error text via await response.text()

A hostile or misbehaving Nextcloud endpoint could stream an unbounded body
(no content-length) into memory, pressuring or hanging the plugin/provider
path. Cap success JSON at 16 MiB via readResponseWithLimit and collapse error
bodies to an 8 KiB readResponseTextSnippet, cancelling the stream on overflow.
The 'message sent but receipt JSON unreadable -> unknown' fallback is
preserved (an over-limit body now also routes through the existing catch).

This is the symmetric counterpart to the #95103/#95108 response-limit
campaign, reusing the shared @openclaw/media-core helpers (newly re-exported
from plugin-sdk/response-limit-runtime for plugin consumers).

* fix(nextcloud-talk): bound error bodies via public readResponseTextLimited (no new plugin-SDK surface)

Re-exporting readResponseTextSnippet from plugin-sdk/response-limit-runtime
pushed the public plugin-SDK export count past its surface budget, failing
plugin-sdk-surface-report.test.ts. Drop that re-export and instead bound the
Nextcloud Talk send/reaction error bodies through the already-public
readResponseTextLimited (openclaw/plugin-sdk/provider-http), collapsing the
bounded 8 KiB prefix to a short, log-safe snippet locally. Behavior is
unchanged for callers; no new plugin-SDK surface is introduced.

Success JSON still reads through readResponseWithLimit (16 MiB cap). The
committed bounded-response-reads Vitest suite continues to prove the caps
hold against 17 MiB streamed bodies with no content-length.

* fix(nextcloud-talk): reuse shared readProviderJsonResponse for send success JSON

The send success receipt parsed JSON by hand via readResponseWithLimit + a
local NEXTCLOUD_TALK_JSON_MAX_BYTES cap + JSON.parse(TextDecoder.decode(...)),
duplicating the shared provider-http helper that the sibling room-info.ts and
bot-preflight.ts already use. extensions/AGENTS.md forbids re-implementing
shared helpers locally.

Swap the hand-rolled block for the one-stop
readProviderJsonResponse<{ ocs?: ... }>(response, "Nextcloud Talk send"), which
reads through the same bounded reader and throws on overflow/malformed JSON, so
the outer try/catch still keeps the "unknown" receipt and behavior is
equivalent. The error path keeps readResponseTextLimited (text, not JSON).

(cherry picked from commit d577cb2fe9)
2026-07-14 01:50:20 -07:00
wangmiao0668000666 ad47570182 fix(googlechat): replace unbounded response.json() with readProviderJsonResponse (#96772)
* fix(googlechat): replace unbounded response.json() with readProviderJsonResponse

Replace the local readGoogleChatJsonResponse and
readGoogleChatCertsResponse wrappers with the existing SDK helper
readProviderJsonResponse (from openclaw/plugin-sdk/provider-http) so the
Google Chat API JSON responses are bounded at 16 MiB, matching the
non-streaming cap already used by 15+ other extensions.

What changed:
- extensions/googlechat/src/api.ts: readGoogleChatJsonResponse now
  delegates to readProviderJsonResponse. Removed the local try/catch
  wrapper.
- extensions/googlechat/src/auth.ts: readGoogleChatCertsResponse now
  delegates to readProviderJsonResponse. Error message preserved.
  Removed the local try/catch wrapper.

This PR applies the same pattern as Alix-007's #96042, #96038 (lmstudio,
provider JSON reads). No SDK promotion needed — readProviderJsonResponse
is already available in openclaw/plugin-sdk/provider-http.

* fix(googlechat): add inline bounded-read regression tests

Co-Authored-By: Claude <noreply@anthropic.com>

* fix(googlechat): remove unused variable flagged by oxlint

Co-Authored-By: Claude <noreply@anthropic.com>

* fix(googlechat): bound api error body reads

---------

Co-authored-by: Claude <noreply@anthropic.com>
Co-authored-by: Vincent Koc <vincentkoc@ieee.org>
(cherry picked from commit 4f3d81b918)
2026-07-14 01:50:20 -07:00
Peter Steinberger 5fbb28544d fix(browser): reject credentialed page URLs safely (#102952)
Co-authored-by: bitkyc08 <bitkyc08@gmail.com>
(cherry picked from commit d5fb4903f1)
2026-07-14 01:47:23 -07:00
Alix-007 cb6325f056 fix(google): add timeout to Vertex ADC token refresh (#102050)
* fix(google): add timeout to Vertex ADC token refresh

* test(google): consolidate ADC timeout proof

* fix(google): bound all ADC token refreshes

* test(google): observe ADC timeout before advancing time

* fix(google): keep dependency timeout claims exact

* fix(google): bound library-managed ADC refreshes

* fix(google): recover after ADC refresh timeout

---------

Co-authored-by: Peter Steinberger <steipete@gmail.com>
(cherry picked from commit e5259fa8bb)
2026-07-14 01:47:14 -07:00
Dallin Romney 95dcba5345 fix(google): bound Vertex token response bodies
Partial prerequisite backport from aaf5ab910c (#100483).

(cherry picked from commit 8a7a6acb6d)
2026-07-14 01:46:27 -07:00
wangmiao0668000666 1918ea2563 fix(google-meet): contain node host stream failures (#102105)
Co-authored-by: Peter Steinberger <steipete@gmail.com>
(cherry picked from commit 624dfa6cf6)
2026-07-14 01:45:38 -07:00
cxbAsDev a0d0b92c37 fix(extensions/huggingface): bound model discovery JSON response read to prevent OOM (#101079)
* fix(extensions/huggingface): bound model discovery JSON response read to prevent OOM

* test(huggingface): prove bounded discovery cleanup

* test(huggingface): avoid unbound reader assertions

---------

Co-authored-by: Peter Steinberger <steipete@gmail.com>
(cherry picked from commit a464620141)
2026-07-14 01:45:24 -07:00
huangjianxiong ac2ec7759c fix(openai): bound Codex OAuth token response body reads with readResponseWithLimit (#99479)
* fix(openai): bound Codex OAuth token response body reads with readResponseWithLimit

Replace unbounded response.arrayBuffer() in postTokenForm with
readResponseWithLimit using a 1 MiB cap to prevent OOM from oversized
token endpoint responses. Add real node:http loopback server tests.

* fix(openai): wrap readResponseWithLimit result in Uint8Array for TS BodyInit compat

- Fixes TS2345: Buffer<ArrayBufferLike> not assignable to BodyInit
- Resolves check-prod-types, check-test-types, and
  check-additional-extension-package-boundary CI failures

Ref. https://github.com/openclaw/openclaw/pull/99479

* test(openai): verify OAuth response release

---------

Co-authored-by: Peter Steinberger <steipete@gmail.com>
(cherry picked from commit a89fe705b8)
2026-07-14 01:45:17 -07:00
wings1029 f860bc32f5 fix(discord): bound gateway metadata response body reads to prevent OOM (#98682)
* fix(discord): bound gateway metadata response body reads to prevent OOM

The materializeGuardedResponse helper in the Discord gateway metadata path
buffered the full upstream Response body via response.arrayBuffer() without
any size cap. A malicious or malfunctioning /gateway/bot endpoint that returns
an oversized payload could exhaust gateway memory.

Replace arrayBuffer() with readResponseWithLimit(4 MiB), consistent with
DISCORD_API_RESPONSE_BODY_LIMIT_BYTES in api.ts. Overflow throws an Error
with the byte counts.

Co-Authored-By: Claude <noreply@anthropic.com>

* fix(discord): wrap readResponseWithLimit result in Uint8Array for type compat

readResponseWithLimit returns Buffer which is not assignable to BodyInit in
the undici Response constructor type. Wrap in new Uint8Array() to satisfy the
boundary dts check. Also remove testExports export and mock fetchWithSsrFGuard
in tests via vi.hoisted + vi.mock to avoid leaking internal test-only exports.

Co-Authored-By: Claude <noreply@anthropic.com>

* test(discord): tighten gateway metadata proof

---------

Co-authored-by: Claude <noreply@anthropic.com>
Co-authored-by: Peter Steinberger <steipete@gmail.com>
(cherry picked from commit fc77c2b04b)
2026-07-14 01:45:10 -07:00
mushuiyu886 daf5d96c05 fix(browser): bound client fetch success JSON reads (#100889)
* fix(browser): bound client fetch success JSON reads

* fix(browser): preserve supported response body sizes

* docs(changelog): note browser response bounds

* chore: keep release changelog owner-only

---------

Co-authored-by: Peter Steinberger <steipete@gmail.com>
(cherry picked from commit 8f7d0a36f9)
2026-07-14 01:44:18 -07:00
wings1029 62bfb62ba9 fix(browser): bound error body read in fetchHttpJson to prevent OOM (#98455)
* fix(browser): bound error body read in fetchHttpJson to prevent OOM

* fix(browser): enforce strict error response limit

---------

Co-authored-by: Peter Steinberger <58493+steipete@users.noreply.github.com>
(cherry picked from commit cc0980cb7a)
2026-07-14 01:44:10 -07:00
Agustin Rivera 391b5d3204 fix(imessage): require authorization for group actions (#97961)
(cherry picked from commit 587eefe5ad)
2026-07-14 01:43:29 -07:00
Alix-007 a817aec1cf fix(inworld): bound TTS audio, voices, and error response reads to prevent OOM (#95416)
* fix(inworld): bound TTS audio, voices, and error response reads to prevent OOM

* fix(inworld): enforce decoded TTS audio cap

---------

Co-authored-by: Vincent Koc <vincentkoc@ieee.org>
Co-authored-by: Vincent Koc <25068+vincentkoc@users.noreply.github.com>
(cherry picked from commit 4c8470c069)
2026-07-14 01:42:40 -07:00
Alix-007 db0d55f5ff fix(zai): bound Z.AI endpoint-probe error body reads to prevent OOM (#97540)
Co-authored-by: Vincent Koc <vincentkoc@ieee.org>
(cherry picked from commit 411a5e63be)
2026-07-14 01:42:32 -07:00
Alix-007 cfa366feca fix(discord): bound REST response body to prevent OOM flood (#95412)
The Discord REST main response path read the body with an unbounded
await response.text() before JSON-parsing it. A controlled or hijacked
endpoint could stream an arbitrarily large body and exhaust memory (OOM).

Wrap the read in the canonical readResponseWithLimit helper with an 8 MiB
cap (well above any legitimate Discord JSON payload) plus an idle timeout
tied to the request timeout, so the stream is cancelled at the cap or on
stall instead of buffering unbounded. Normal payloads still parse fully.

This mirrors PR #95108 which bounded the analogous Anthropic Messages
error-response read with the same helper.

(cherry picked from commit 2d2a50c00d)
2026-07-14 01:42:08 -07:00
Vincent Koc cf64cf788e test(qa): make memory channel scenario wait for final answer 2026-06-29 18:34:10 -07:00
Vincent Koc 848c4e6a39 test(qa): accept crabline multi-channel capabilities 2026-06-29 18:04:54 -07:00
Vincent Koc d377c0f910 fix(release): use workspace host deps in release lockfile 2026-06-29 17:43:39 -07:00
Vincent Koc 9b703d0cd6 test(qa): accept async image fixture coverage 2026-06-29 17:14:33 -07:00
Vincent Koc 5f4fa97835 test(codex): harden run-attempt temp cleanup 2026-06-29 15:48:41 -07:00
Vincent Koc 65e4b0a21d chore(release): prepare 2026.6.11 2026-06-29 15:34:04 -07:00
Vincent Koc 4f9d5864f0 chore(release): prepare 2026.6.11-beta.2 2026-06-28 12:03:06 -07:00
Vincent Koc 8346e87808 fix(telegram): recover stalled ingress spool claims
Backport of #97118 to release/2026.6.11.
2026-06-28 10:57:49 -07:00
Vincent Koc 3b315d1dfe fix(qa): align runtime parity evidence with Codex 2026-06-24 21:02:02 +08:00
Vincent Koc 9450340129 fix(qa): issue unique mock tool call ids 2026-06-24 16:33:34 +08:00
Vincent Koc bed6726636 chore(release): prepare 2026.6.11-beta.1 2026-06-24 13:39:11 +08:00
Vincent Koc 0671c08900 chore(release): close out 2026.6.10 on main (#96271)
* chore(release): close out 2026.6.10 on main

* chore(release): align native app metadata for 2026.6.10

* chore(release): sync Android 2026.6.10 notes

* docs(changelog): preserve 2026.6.9 history

* docs(changelog): preserve 2026.6.9 history
2026-06-24 11:51:14 +08:00
dongdong 7b9f4aefa2 fix(nextcloud-talk): ignore signed non-message webhook events (#96243)
* fix(nextcloud-talk): ignore non-message webhook events

* fix(nextcloud-talk): acknowledge lifecycle webhook events

---------

Co-authored-by: Jasmine Zhang <jasminezhang@JasminedeMac-mini.local>
Co-authored-by: Vincent Koc <25068+vincentkoc@users.noreply.github.com>
2026-06-24 11:15:48 +08:00
Wynne668 d15e89a83e fix(workboard): hide archived cards in CLI list by default (#94562)
* fix(workboard): hide archived cards in CLI list by default

The `openclaw workboard list` CLI printed soft-archived cards, while the
`workboard_list` agent tool and the `/workboard list` command both hide
cards with `metadata.archivedAt` set unless archives are requested. Users
who archived cards still saw them in CLI output and assumed archive failed.

Filter archived cards by default in the CLI list handler and add an
`--include-archived` flag mirroring the tool's `includeArchived` option, so
all three list surfaces share one default. Docs updated to match.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>

* fix(workboard): preserve json list archive visibility

* fix(workboard): preserve json list archive visibility

---------

Co-authored-by: Claude Opus 4.8 <noreply@anthropic.com>
Co-authored-by: Vincent Koc <vincentkoc@ieee.org>
2026-06-24 10:57:06 +08:00
Vincent Koc 2ad2e4f2dc perf(codex): index rollout transcript ids 2026-06-24 09:23:42 +08:00
Vincent Koc 28a90b0e82 perf(browser): index role snapshot references 2026-06-24 09:23:19 +08:00
Sarah Fortune d9298a74be fix(codex): prefer gateway-managed generated images 2026-06-23 17:47:04 -07:00