mirror of
https://github.com/wavetermdev/backup.git
synced 2026-04-22 15:26:58 -07:00
Compare commits
5 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| a221655027 | |||
| b0025e4b1f | |||
| ab200d624d | |||
| abe4ae6fea | |||
| 8bb989fc6f |
@@ -0,0 +1,83 @@
|
||||
# Workflow to manage bumping the package version and pushing it to the target branch with a new tag.
|
||||
# This workflow uses a GitHub App to bypass branch protection and uses the GitHub API directly to ensure commits and tags are signed.
|
||||
# For more information, see this doc: https://github.com/Nautilus-Cyberneering/pygithub/blob/main/docs/how_to_sign_automatic_commits_in_github_actions.md
|
||||
|
||||
name: Bump Version
|
||||
run-name: "branch: ${{ github.ref_name }}; semver-bump: ${{ inputs.bump }}; prerelease: ${{ inputs.is-prerelease }}"
|
||||
on:
|
||||
workflow_dispatch:
|
||||
inputs:
|
||||
bump:
|
||||
description: SemVer Bump
|
||||
required: true
|
||||
type: choice
|
||||
default: none
|
||||
options:
|
||||
- none
|
||||
- patch
|
||||
- minor
|
||||
- major
|
||||
is-prerelease:
|
||||
description: Is Prerelease
|
||||
required: true
|
||||
type: boolean
|
||||
default: true
|
||||
env:
|
||||
NODE_VERSION: "22.5.1"
|
||||
jobs:
|
||||
bump-version:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- name: Get App Token
|
||||
uses: actions/create-github-app-token@v1
|
||||
id: app-token
|
||||
with:
|
||||
app-id: ${{ vars.WAVE_BUILDER_APPID }}
|
||||
private-key: ${{ secrets.WAVE_BUILDER_KEY }}
|
||||
- uses: actions/checkout@v4
|
||||
with:
|
||||
token: ${{ steps.app-token.outputs.token }}
|
||||
|
||||
# General build dependencies
|
||||
- uses: actions/setup-node@v4
|
||||
with:
|
||||
node-version: ${{env.NODE_VERSION}}
|
||||
- name: Install Yarn
|
||||
run: |
|
||||
corepack enable
|
||||
yarn install
|
||||
- name: Install Task
|
||||
uses: arduino/setup-task@v2
|
||||
with:
|
||||
version: 3.x
|
||||
repo-token: ${{ secrets.GITHUB_TOKEN }}
|
||||
|
||||
- name: "Bump Version: ${{ inputs.bump }}"
|
||||
id: bump-version
|
||||
run: echo "WAVETERM_VERSION=$( task version -- ${{ inputs.bump }} ${{inputs.is-prerelease}} )" >> "$GITHUB_OUTPUT"
|
||||
shell: bash
|
||||
|
||||
- name: "Push version bump: ${{ steps.bump-version.outputs.WAVETERM_VERSION }}"
|
||||
run: |
|
||||
# Create a new commit for the package version bump in package.json
|
||||
export VERSION=${{ steps.bump-version.outputs.WAVETERM_VERSION }}
|
||||
export MESSAGE="chore: bump package version to $VERSION"
|
||||
export FILE=package.json
|
||||
export BRANCH=${{github.ref_name}}
|
||||
export SHA=$( git rev-parse $BRANCH:$FILE )
|
||||
export CONTENT=$( base64 -i $FILE )
|
||||
gh api --method PUT /repos/:owner/:repo/contents/$FILE \
|
||||
--field branch="$BRANCH" \
|
||||
--field message="$MESSAGE" \
|
||||
--field content="$CONTENT" \
|
||||
--field sha="$SHA"
|
||||
|
||||
# Fetch the new commit and create a tag referencing it
|
||||
git fetch
|
||||
export TAG_SHA=$( git rev-parse origin/$BRANCH )
|
||||
gh api --method POST /repos/:owner/:repo/git/refs \
|
||||
--field ref="refs/tags/v$VERSION" \
|
||||
--field sha="$TAG_SHA"
|
||||
shell: bash
|
||||
env:
|
||||
GH_TOKEN: ${{ steps.app-token.outputs.token }}
|
||||
+2
-2
@@ -76,7 +76,7 @@ function buildWaveShell {
|
||||
}
|
||||
function buildWaveSrv {
|
||||
# adds -extldflags=-static, *only* on linux (macos does not support fully static binaries) to avoid a glibc dependency
|
||||
(cd wavesrv; CGO_ENABLED=1 GOARCH=$1 go build -tags "osusergo,netgo,sqlite_omit_load_extension" -ldflags "-linkmode 'external' -extldflags=-static $GO_LDFLAGS -X main.WaveVersion=$WAVESRV_VERSION" -o ../bin/wavesrv.$1 ./cmd)
|
||||
(cd wavesrv; CGO_ENABLED=1 GOARCH=$1 go build -tags "osusergo,netcgo,sqlite_omit_load_extension" -ldflags "-linkmode 'external' -extldflags=-static $GO_LDFLAGS -X main.WaveVersion=$WAVESRV_VERSION" -o ../bin/wavesrv.$1 ./cmd)
|
||||
}
|
||||
buildWaveShell darwin amd64
|
||||
buildWaveShell darwin arm64
|
||||
@@ -90,7 +90,7 @@ yarn run electron-builder -c electron-builder.config.js -l -p never
|
||||
# @scripthaus command build-wavesrv
|
||||
WAVESRV_VERSION=$(node -e 'console.log(require("./version.js"))')
|
||||
cd wavesrv
|
||||
CGO_ENABLED=1 go build -tags "osusergo,netgo,sqlite_omit_load_extension" -ldflags "-X main.BuildTime=$(date +'%Y%m%d%H%M') -X main.WaveVersion=$WAVESRV_VERSION" -o ../bin/wavesrv ./cmd
|
||||
CGO_ENABLED=1 go build -tags "osusergo,netcgo,sqlite_omit_load_extension" -ldflags "-X main.BuildTime=$(date +'%Y%m%d%H%M') -X main.WaveVersion=$WAVESRV_VERSION" -o ../bin/wavesrv ./cmd
|
||||
```
|
||||
|
||||
```bash
|
||||
|
||||
@@ -9,6 +9,7 @@ export const LINE_SETTINGS = "lineSettings";
|
||||
export const CLIENT_SETTINGS = "clientSettings";
|
||||
export const TAB_SWITCHER = "tabSwitcher";
|
||||
export const USER_INPUT = "userInput";
|
||||
export const NEW_WAVE = "newWave";
|
||||
|
||||
export const LineContainer_Main = "main";
|
||||
export const LineContainer_History = "history";
|
||||
|
||||
File diff suppressed because one or more lines are too long
|
After Width: | Height: | Size: 13 MiB |
@@ -10,3 +10,4 @@ export { SessionSettingsModal } from "./sessionsettings";
|
||||
export { ScreenSettingsModal } from "./screensettings";
|
||||
export { LineSettingsModal } from "./linesettings";
|
||||
export { UserInputModal } from "./userinput";
|
||||
export { NewWaveModal } from "./newwave";
|
||||
|
||||
@@ -0,0 +1,95 @@
|
||||
.newwave-modal {
|
||||
width: 640px;
|
||||
border-radius: 8px;
|
||||
border: 0.5px solid rgba(255, 255, 255, 0.12);
|
||||
background: #232323;
|
||||
box-shadow: 0px 8px 32px 0px rgba(0, 0, 0, 0.25);
|
||||
|
||||
.wave-modal-content .wave-modal-body {
|
||||
padding: 0;
|
||||
gap: 8px;
|
||||
|
||||
.wave-modal-body-inner {
|
||||
gap: 24px;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
|
||||
header.newwave-header {
|
||||
padding: 24px 32px 0;
|
||||
position: relative;
|
||||
flex-direction: column;
|
||||
gap: 12px;
|
||||
border-bottom: none;
|
||||
|
||||
.modal-title {
|
||||
text-align: left;
|
||||
font-size: 20px;
|
||||
font-weight: normal;
|
||||
}
|
||||
|
||||
.close {
|
||||
position: absolute;
|
||||
right: 32px;
|
||||
top: 24px;
|
||||
}
|
||||
}
|
||||
|
||||
.content.newwave-content {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
align-items: flex-start;
|
||||
width: 100%;
|
||||
margin-bottom: 0;
|
||||
gap: 10px;
|
||||
|
||||
.item {
|
||||
width: 100%;
|
||||
line-height: 19px;
|
||||
font-weight: 400;
|
||||
padding-left: 32px;
|
||||
padding-right: 32px;
|
||||
|
||||
&.image-item {
|
||||
padding: 0 0;
|
||||
height: 360px;
|
||||
}
|
||||
|
||||
img {
|
||||
width: 100%;
|
||||
margin-bottom: -45px;
|
||||
}
|
||||
|
||||
span {
|
||||
font-weight: 600;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
footer {
|
||||
padding: 0 32px 24px;
|
||||
display: flex;
|
||||
justify-content: flex-end;
|
||||
|
||||
.button-wrapper {
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
|
||||
button {
|
||||
font-size: 15px;
|
||||
margin-top: 16px;
|
||||
|
||||
&:last-child {
|
||||
margin-left: 10px;
|
||||
}
|
||||
}
|
||||
|
||||
button.disabled-button {
|
||||
cursor: default;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,78 @@
|
||||
// Copyright 2023, Command Line Inc.
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
import * as React from "react";
|
||||
import * as mobxReact from "mobx-react";
|
||||
import { boundMethod } from "autobind-decorator";
|
||||
import { Modal, Button } from "@/elements";
|
||||
import { getApi } from "@/models";
|
||||
|
||||
import newwave from "@/assets/new-wave-screenshot.svg";
|
||||
|
||||
import "./newwave.less";
|
||||
|
||||
@mobxReact.observer
|
||||
class NewWaveModal extends React.Component<{ onClose: () => void }, {}> {
|
||||
@boundMethod
|
||||
handleDownloadOldWave(): void {
|
||||
getApi().openExternalLink("https://www.waveterm.dev/download-legacy");
|
||||
}
|
||||
|
||||
@boundMethod
|
||||
handleDownloadNewWave(): void {
|
||||
getApi().openExternalLink("https://www.waveterm.dev/download");
|
||||
}
|
||||
|
||||
@boundMethod
|
||||
handleClose(): void {
|
||||
this.props.onClose();
|
||||
}
|
||||
|
||||
render() {
|
||||
return (
|
||||
<Modal className="newwave-modal">
|
||||
<div className="wave-modal-body">
|
||||
<div className="wave-modal-body-inner">
|
||||
<header className="newwave-header unselectable">
|
||||
<div className="modal-title">A New Wave is Coming!</div>
|
||||
<i className="fa-regular fa-xmark-large close" onClick={this.handleClose}></i>
|
||||
</header>
|
||||
<div className="content newwave-content unselectable">
|
||||
<div className="item">
|
||||
We are excited to share that after 3-months of work, and almost 1000 new commits, Wave
|
||||
v0.8 is now available. It features a new layout engine for screen splitting, improved
|
||||
remote file browsing and previewing, improved performance, and a new design. We've also
|
||||
removed some of the more controversial features that took over the shell experience and
|
||||
overrode things like completions, history, and prompts.
|
||||
</div>
|
||||
<div className="item">
|
||||
The new build is a fresh start, and a clean break from the current version. As such,
|
||||
your history, settings, and configuration will <i>not</i> be carried over. If you'd like
|
||||
to continue to run the legacy version, you will need to download it separately.
|
||||
</div>
|
||||
<div className="item image-item">
|
||||
<img src={newwave} height="400px" />
|
||||
</div>
|
||||
<div className="item">
|
||||
You can download Wave v0.8 now or wait for an auto-update next week. The legacy version
|
||||
will be available via separate download page.
|
||||
</div>
|
||||
</div>
|
||||
<footer className="unselectable">
|
||||
<div className="button-wrapper">
|
||||
<Button className="secondary" onClick={this.handleDownloadOldWave}>
|
||||
Legacy Download
|
||||
</Button>
|
||||
</div>
|
||||
<div className="button-wrapper">
|
||||
<Button onClick={this.handleDownloadNewWave}>Upgrade to Wave v0.8</Button>
|
||||
</div>
|
||||
</footer>
|
||||
</div>
|
||||
</div>
|
||||
</Modal>
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
export { NewWaveModal };
|
||||
@@ -5,14 +5,34 @@ import * as React from "react";
|
||||
import * as mobxReact from "mobx-react";
|
||||
import { GlobalModel } from "@/models";
|
||||
import { TosModal } from "./tos";
|
||||
import { NewWaveModal } from "./newwave";
|
||||
|
||||
const SessionStorageKey = "newWaveRendered";
|
||||
|
||||
@mobxReact.observer
|
||||
class ModalsProvider extends React.Component {
|
||||
class ModalsProvider extends React.Component<{}, {}> {
|
||||
constructor(props) {
|
||||
super(props);
|
||||
this.handleNewWaveOnClose = this.handleNewWaveOnClose.bind(this);
|
||||
}
|
||||
|
||||
handleNewWaveOnClose() {
|
||||
sessionStorage.setItem(SessionStorageKey, "1");
|
||||
this.forceUpdate();
|
||||
}
|
||||
|
||||
render() {
|
||||
let store = GlobalModel.modalsModel.store.slice();
|
||||
|
||||
if (GlobalModel.needsTos()) {
|
||||
return <TosModal />;
|
||||
}
|
||||
|
||||
const newWaveRendered = sessionStorage.getItem(SessionStorageKey);
|
||||
if (!newWaveRendered) {
|
||||
return <NewWaveModal onClose={this.handleNewWaveOnClose} />;
|
||||
}
|
||||
|
||||
let rtn: JSX.Element[] = [];
|
||||
for (let i = 0; i < store.length; i++) {
|
||||
let entry = store[i];
|
||||
|
||||
@@ -13,6 +13,7 @@ import {
|
||||
ScreenSettingsModal,
|
||||
LineSettingsModal,
|
||||
UserInputModal,
|
||||
NewWaveModal,
|
||||
} from "@/modals";
|
||||
import * as constants from "@/app/appconst";
|
||||
|
||||
@@ -27,6 +28,7 @@ const modalsRegistry: { [key: string]: React.ComponentType } = {
|
||||
[constants.LINE_SETTINGS]: LineSettingsModal,
|
||||
[constants.TAB_SWITCHER]: TabSwitcherModal,
|
||||
[constants.USER_INPUT]: UserInputModal,
|
||||
[constants.NEW_WAVE]: NewWaveModal,
|
||||
};
|
||||
|
||||
export { modalsRegistry };
|
||||
|
||||
@@ -18,6 +18,7 @@ import (
|
||||
"os/exec"
|
||||
"regexp"
|
||||
"sort"
|
||||
"strconv"
|
||||
"strings"
|
||||
"syscall"
|
||||
"unicode/utf8"
|
||||
@@ -673,3 +674,26 @@ func GetFirstLine(s string) string {
|
||||
}
|
||||
return s[0:idx]
|
||||
}
|
||||
|
||||
func TrimQuotes(s string) (string, bool) {
|
||||
if len(s) > 2 && s[0] == '"' {
|
||||
trimmed, err := strconv.Unquote(s)
|
||||
if err != nil {
|
||||
return s, false
|
||||
}
|
||||
return trimmed, true
|
||||
}
|
||||
return s, false
|
||||
}
|
||||
|
||||
func TryTrimQuotes(s string) string {
|
||||
trimmed, _ := TrimQuotes(s)
|
||||
return trimmed
|
||||
}
|
||||
|
||||
func ReplaceQuotes(s string, shouldReplace bool) string {
|
||||
if shouldReplace {
|
||||
return strconv.Quote(s)
|
||||
}
|
||||
return s
|
||||
}
|
||||
|
||||
+1
-1
@@ -17,7 +17,7 @@ require (
|
||||
github.com/jmoiron/sqlx v1.3.5
|
||||
github.com/kevinburke/ssh_config v1.2.0
|
||||
github.com/mattn/go-sqlite3 v1.14.16
|
||||
github.com/sashabaranov/go-openai v1.9.0
|
||||
github.com/sashabaranov/go-openai v1.30.0
|
||||
github.com/sawka/txwrap v0.1.2
|
||||
github.com/wavetermdev/waveterm/waveshell v0.0.0
|
||||
golang.org/x/crypto v0.24.0
|
||||
|
||||
@@ -51,6 +51,8 @@ github.com/rogpeppe/go-internal v1.10.1-0.20230524175051-ec119421bb97 h1:3RPlVWz
|
||||
github.com/rogpeppe/go-internal v1.10.1-0.20230524175051-ec119421bb97/go.mod h1:ddIwULY96R17DhadqLgMfk9H9tvdUzkipdSkR5nkCZA=
|
||||
github.com/sashabaranov/go-openai v1.9.0 h1:NoiO++IISxxJ1pRc0n7uZvMGMake0G+FJ1XPwXtprsA=
|
||||
github.com/sashabaranov/go-openai v1.9.0/go.mod h1:lj5b/K+zjTSFxVLijLSTDZuP7adOgerWeFyZLUhAKRg=
|
||||
github.com/sashabaranov/go-openai v1.30.0 h1:fHv9urGxABfm885xGWsXFSk5cksa+8dJ4jGli/UQQcI=
|
||||
github.com/sashabaranov/go-openai v1.30.0/go.mod h1:lj5b/K+zjTSFxVLijLSTDZuP7adOgerWeFyZLUhAKRg=
|
||||
github.com/sawka/txwrap v0.1.2 h1:v8xS0Z1LE7/6vMZA81PYihI+0TSR6Zm1MalzzBIuXKc=
|
||||
github.com/sawka/txwrap v0.1.2/go.mod h1:T3nlw2gVpuolo6/XEetvBbk1oMXnY978YmBFy1UyHvw=
|
||||
github.com/skeema/knownhosts v1.3.0 h1:AM+y0rI04VksttfwjkSTNQorvGqmwATnvnAHpSgc0LY=
|
||||
|
||||
@@ -167,7 +167,14 @@ func SendTelemetry(ctx context.Context, force bool) error {
|
||||
log.Printf("[pcloud] sending telemetry data\n")
|
||||
dayStr := telemetry.GetCurDayStr()
|
||||
defaultShellType := shellapi.DetectLocalShellType()
|
||||
input := TelemetryInputType{UserId: clientData.UserId, ClientId: clientData.ClientId, CurDay: dayStr, DefaultShell: defaultShellType, Activity: activity}
|
||||
input := TelemetryInputType{
|
||||
UserId: clientData.UserId,
|
||||
ClientId: clientData.ClientId,
|
||||
AppType: "wave",
|
||||
CurDay: dayStr,
|
||||
DefaultShell: defaultShellType,
|
||||
Activity: activity,
|
||||
}
|
||||
req, err := makeAnonPostReq(ctx, TelemetryUrl, input)
|
||||
if err != nil {
|
||||
return err
|
||||
|
||||
@@ -22,6 +22,7 @@ type NoTelemetryInputType struct {
|
||||
type TelemetryInputType struct {
|
||||
UserId string `json:"userid"`
|
||||
ClientId string `json:"clientid"`
|
||||
AppType string `json:"apptype"`
|
||||
CurDay string `json:"curday"`
|
||||
DefaultShell string `json:"defaultshell"`
|
||||
Activity []*telemetry.ActivityType `json:"activity"`
|
||||
|
||||
@@ -190,7 +190,7 @@ func RunCompletionStream(ctx context.Context, opts *sstore.OpenAIOptsType, promp
|
||||
pk := packet.MakeOpenAIPacket()
|
||||
pk.Index = choice.Index
|
||||
pk.Text = choice.Delta.Content
|
||||
pk.FinishReason = choice.FinishReason
|
||||
pk.FinishReason = string(choice.FinishReason)
|
||||
rtn <- pk
|
||||
}
|
||||
}
|
||||
@@ -209,7 +209,7 @@ func marshalResponse(resp openaiapi.ChatCompletionResponse) []*packet.OpenAIPack
|
||||
choicePk := packet.MakeOpenAIPacket()
|
||||
choicePk.Index = choice.Index
|
||||
choicePk.Text = choice.Message.Content
|
||||
choicePk.FinishReason = choice.FinishReason
|
||||
choicePk.FinishReason = string(choice.FinishReason)
|
||||
rtn = append(rtn, choicePk)
|
||||
}
|
||||
return rtn
|
||||
|
||||
@@ -1314,14 +1314,15 @@ func (wsh *WaveshellProc) RunInstall(autoInstall bool) {
|
||||
wsh.WriteToPtyBuffer("*error: cannot install on a local remote\n")
|
||||
return
|
||||
}
|
||||
_, err = shellapi.MakeShellApi(packet.ShellType_bash)
|
||||
sapi, err := shellapi.MakeShellApi(wsh.GetShellType())
|
||||
if err != nil {
|
||||
wsh.WriteToPtyBuffer("*error: %v\n", err)
|
||||
return
|
||||
}
|
||||
if wsh.Client == nil {
|
||||
remoteDisplayName := fmt.Sprintf("%s [%s]", remoteCopy.RemoteAlias, remoteCopy.RemoteCanonicalName)
|
||||
client, err := ConnectToClient(makeClientCtx, remoteCopy.SSHOpts, remoteDisplayName)
|
||||
sshAuthSock, _ := exec.CommandContext(makeClientCtx, sapi.GetLocalShellPath(), "-c", "echo \"${SSH_AUTH_SOCK}\"").CombinedOutput()
|
||||
client, err := ConnectToClient(makeClientCtx, remoteCopy.SSHOpts, remoteDisplayName, strings.TrimSpace(string(sshAuthSock)))
|
||||
if err != nil {
|
||||
statusErr := fmt.Errorf("ssh cannot connect to client: %w", err)
|
||||
wsh.setInstallErrorStatus(statusErr)
|
||||
@@ -1614,7 +1615,8 @@ func (wsh *WaveshellProc) createWaveshellSession(clientCtx context.Context, remo
|
||||
wsSession = shexec.CmdWrap{Cmd: ecmd}
|
||||
} else if wsh.Client == nil {
|
||||
remoteDisplayName := fmt.Sprintf("%s [%s]", remoteCopy.RemoteAlias, remoteCopy.RemoteCanonicalName)
|
||||
client, err := ConnectToClient(clientCtx, remoteCopy.SSHOpts, remoteDisplayName)
|
||||
sshAuthSock, _ := exec.CommandContext(clientCtx, sapi.GetLocalShellPath(), "-c", "echo \"${SSH_AUTH_SOCK}\"").CombinedOutput()
|
||||
client, err := ConnectToClient(clientCtx, remoteCopy.SSHOpts, remoteDisplayName, strings.TrimSpace(string(sshAuthSock)))
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("ssh cannot connect to client: %w", err)
|
||||
}
|
||||
|
||||
@@ -24,10 +24,12 @@ import (
|
||||
"github.com/kevinburke/ssh_config"
|
||||
"github.com/skeema/knownhosts"
|
||||
"github.com/wavetermdev/waveterm/waveshell/pkg/base"
|
||||
"github.com/wavetermdev/waveterm/waveshell/pkg/utilfn"
|
||||
"github.com/wavetermdev/waveterm/wavesrv/pkg/scbus"
|
||||
"github.com/wavetermdev/waveterm/wavesrv/pkg/sstore"
|
||||
"github.com/wavetermdev/waveterm/wavesrv/pkg/userinput"
|
||||
"golang.org/x/crypto/ssh"
|
||||
"golang.org/x/crypto/ssh/agent"
|
||||
xknownhosts "golang.org/x/crypto/ssh/knownhosts"
|
||||
)
|
||||
|
||||
@@ -68,7 +70,7 @@ func createDummySigner() ([]ssh.Signer, error) {
|
||||
// they were successes. An error in this function prevents any other
|
||||
// keys from being attempted. But if there's an error because of a dummy
|
||||
// file, the library can still try again with a new key.
|
||||
func createPublicKeyCallback(connCtx context.Context, sshKeywords *SshKeywords, passphrase string) func() ([]ssh.Signer, error) {
|
||||
func createPublicKeyCallback(connCtx context.Context, sshKeywords *SshKeywords, passphrase string, authSockSignersExt []ssh.Signer, agentClient agent.ExtendedAgent) func() ([]ssh.Signer, error) {
|
||||
var identityFiles []string
|
||||
existingKeys := make(map[string][]byte)
|
||||
|
||||
@@ -86,7 +88,19 @@ func createPublicKeyCallback(connCtx context.Context, sshKeywords *SshKeywords,
|
||||
// require pointer to modify list in closure
|
||||
identityFilesPtr := &identityFiles
|
||||
|
||||
var authSockSigners []ssh.Signer
|
||||
authSockSigners = append(authSockSigners, authSockSignersExt...)
|
||||
authSockSignersPtr := &authSockSigners
|
||||
|
||||
return func() ([]ssh.Signer, error) {
|
||||
// try auth sock
|
||||
if len(*authSockSignersPtr) != 0 {
|
||||
authSockSigner := (*authSockSignersPtr)[0]
|
||||
*authSockSignersPtr = (*authSockSignersPtr)[1:]
|
||||
return []ssh.Signer{authSockSigner}, nil
|
||||
}
|
||||
|
||||
// try manual identity files
|
||||
if len(*identityFilesPtr) == 0 {
|
||||
return nil, fmt.Errorf("no identity files remaining")
|
||||
}
|
||||
@@ -98,6 +112,24 @@ func createPublicKeyCallback(connCtx context.Context, sshKeywords *SshKeywords,
|
||||
// skip this key and try with the next
|
||||
return createDummySigner()
|
||||
}
|
||||
|
||||
unencryptedPrivateKey, err := ssh.ParseRawPrivateKey(privateKey)
|
||||
if err == nil {
|
||||
signer, err := ssh.NewSignerFromKey(unencryptedPrivateKey)
|
||||
if err == nil {
|
||||
if sshKeywords.AddKeysToAgent && agentClient != nil {
|
||||
agentClient.Add(agent.AddedKey{
|
||||
PrivateKey: unencryptedPrivateKey,
|
||||
})
|
||||
}
|
||||
return []ssh.Signer{signer}, err
|
||||
}
|
||||
}
|
||||
if _, ok := err.(*ssh.PassphraseMissingError); !ok {
|
||||
// skip this key and try with the next
|
||||
return createDummySigner()
|
||||
}
|
||||
|
||||
signer, err := ssh.ParsePrivateKey(privateKey)
|
||||
if err == nil {
|
||||
return []ssh.Signer{signer}, err
|
||||
@@ -107,9 +139,17 @@ func createPublicKeyCallback(connCtx context.Context, sshKeywords *SshKeywords,
|
||||
return createDummySigner()
|
||||
}
|
||||
|
||||
signer, err = ssh.ParsePrivateKeyWithPassphrase(privateKey, []byte(passphrase))
|
||||
unencryptedPrivateKey, err = ssh.ParseRawPrivateKeyWithPassphrase(privateKey, []byte(passphrase))
|
||||
if err == nil {
|
||||
return []ssh.Signer{signer}, err
|
||||
signer, err := ssh.NewSignerFromKey(unencryptedPrivateKey)
|
||||
if err == nil {
|
||||
if sshKeywords.AddKeysToAgent && agentClient != nil {
|
||||
agentClient.Add(agent.AddedKey{
|
||||
PrivateKey: unencryptedPrivateKey,
|
||||
})
|
||||
}
|
||||
return []ssh.Signer{signer}, err
|
||||
}
|
||||
}
|
||||
if err != x509.IncorrectPasswordError && err.Error() != "bcrypt_pbkdf: empty password" {
|
||||
// skip this key and try with the next
|
||||
@@ -135,11 +175,22 @@ func createPublicKeyCallback(connCtx context.Context, sshKeywords *SshKeywords,
|
||||
// trying keys
|
||||
return nil, UserInputCancelError{Err: err}
|
||||
}
|
||||
signer, err = ssh.ParsePrivateKeyWithPassphrase(privateKey, []byte(response.Text))
|
||||
|
||||
unencryptedPrivateKey, err = ssh.ParseRawPrivateKeyWithPassphrase(privateKey, []byte([]byte(response.Text)))
|
||||
if err != nil {
|
||||
// skip this key and try with the next
|
||||
return createDummySigner()
|
||||
}
|
||||
signer, err = ssh.NewSignerFromKey(unencryptedPrivateKey)
|
||||
if err != nil {
|
||||
// skip this key and try with the next
|
||||
return createDummySigner()
|
||||
}
|
||||
if sshKeywords.AddKeysToAgent && agentClient != nil {
|
||||
agentClient.Add(agent.AddedKey{
|
||||
PrivateKey: unencryptedPrivateKey,
|
||||
})
|
||||
}
|
||||
return []ssh.Signer{signer}, err
|
||||
}
|
||||
}
|
||||
@@ -538,8 +589,8 @@ func DialContext(ctx context.Context, network string, addr string, config *ssh.C
|
||||
return ssh.NewClient(c, chans, reqs), nil
|
||||
}
|
||||
|
||||
func ConnectToClient(connCtx context.Context, opts *sstore.SSHOpts, remoteDisplayName string) (*ssh.Client, error) {
|
||||
sshConfigKeywords, err := findSshConfigKeywords(opts.SSHHost)
|
||||
func ConnectToClient(connCtx context.Context, opts *sstore.SSHOpts, remoteDisplayName string, sshAuthSock string) (*ssh.Client, error) {
|
||||
sshConfigKeywords, err := findSshConfigKeywords(opts.SSHHost, sshAuthSock)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
@@ -549,7 +600,17 @@ func ConnectToClient(connCtx context.Context, opts *sstore.SSHOpts, remoteDispla
|
||||
return nil, err
|
||||
}
|
||||
|
||||
publicKeyCallback := ssh.PublicKeysCallback(createPublicKeyCallback(connCtx, sshKeywords, opts.SSHPassword))
|
||||
conn, err := net.Dial("unix", sshKeywords.IdentityAgent)
|
||||
var authSockSigners []ssh.Signer
|
||||
var agentClient agent.ExtendedAgent
|
||||
if err != nil {
|
||||
log.Printf("Failed to open Identity Agent Socket: %v", err)
|
||||
} else {
|
||||
agentClient = agent.NewClient(conn)
|
||||
authSockSigners, _ = agentClient.Signers()
|
||||
}
|
||||
|
||||
publicKeyCallback := ssh.PublicKeysCallback(createPublicKeyCallback(connCtx, sshKeywords, opts.SSHPassword, authSockSigners, agentClient))
|
||||
keyboardInteractive := ssh.KeyboardInteractive(createCombinedKbdInteractiveChallenge(connCtx, opts.SSHPassword, remoteDisplayName))
|
||||
passwordCallback := ssh.PasswordCallback(createCombinedPasswordCallbackPrompt(connCtx, opts.SSHPassword, remoteDisplayName))
|
||||
|
||||
@@ -564,7 +625,7 @@ func ConnectToClient(connCtx context.Context, opts *sstore.SSHOpts, remoteDispla
|
||||
|
||||
// exclude gssapi-with-mic and hostbased until implemented
|
||||
authMethodMap := map[string]ssh.AuthMethod{
|
||||
"publickey": ssh.RetryableAuthMethod(publicKeyCallback, len(sshKeywords.IdentityFile)),
|
||||
"publickey": ssh.RetryableAuthMethod(publicKeyCallback, len(sshKeywords.IdentityFile)+len(authSockSigners)),
|
||||
"keyboard-interactive": ssh.RetryableAuthMethod(keyboardInteractive, attemptsAllowed),
|
||||
"password": ssh.RetryableAuthMethod(passwordCallback, attemptsAllowed),
|
||||
}
|
||||
@@ -613,6 +674,8 @@ type SshKeywords struct {
|
||||
PasswordAuthentication bool
|
||||
KbdInteractiveAuthentication bool
|
||||
PreferredAuthentications []string
|
||||
AddKeysToAgent bool
|
||||
IdentityAgent string
|
||||
}
|
||||
|
||||
func combineSshKeywords(opts *sstore.SSHOpts, configKeywords *SshKeywords) (*SshKeywords, error) {
|
||||
@@ -662,6 +725,8 @@ func combineSshKeywords(opts *sstore.SSHOpts, configKeywords *SshKeywords) (*Ssh
|
||||
sshKeywords.PasswordAuthentication = configKeywords.PasswordAuthentication
|
||||
sshKeywords.KbdInteractiveAuthentication = configKeywords.KbdInteractiveAuthentication
|
||||
sshKeywords.PreferredAuthentications = configKeywords.PreferredAuthentications
|
||||
sshKeywords.AddKeysToAgent = configKeywords.AddKeysToAgent
|
||||
sshKeywords.IdentityAgent = configKeywords.IdentityAgent
|
||||
|
||||
return sshKeywords, nil
|
||||
}
|
||||
@@ -669,7 +734,7 @@ func combineSshKeywords(opts *sstore.SSHOpts, configKeywords *SshKeywords) (*Ssh
|
||||
// note that a `var == "yes"` will default to false
|
||||
// but `var != "no"` will default to true
|
||||
// when given unexpected strings
|
||||
func findSshConfigKeywords(hostPattern string) (*SshKeywords, error) {
|
||||
func findSshConfigKeywords(hostPattern string, sshAuthSock string) (*SshKeywords, error) {
|
||||
ssh_config.ReloadConfigs()
|
||||
sshKeywords := &SshKeywords{}
|
||||
var err error
|
||||
@@ -724,5 +789,21 @@ func findSshConfigKeywords(hostPattern string) (*SshKeywords, error) {
|
||||
}
|
||||
sshKeywords.PreferredAuthentications = strings.Split(preferredAuthenticationsRaw, ",")
|
||||
|
||||
addKeysToAgentRaw, err := ssh_config.GetStrict(hostPattern, "AddKeysToAgent")
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
sshKeywords.AddKeysToAgent = (strings.ToLower(addKeysToAgentRaw) == "yes")
|
||||
|
||||
identityAgentRaw, err := ssh_config.GetStrict(hostPattern, "IdentityAgent")
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if identityAgentRaw == "" {
|
||||
sshKeywords.IdentityAgent = base.ExpandHomeDir(utilfn.TryTrimQuotes(strings.TrimSpace(string(sshAuthSock))))
|
||||
} else {
|
||||
sshKeywords.IdentityAgent = base.ExpandHomeDir(utilfn.TryTrimQuotes(identityAgentRaw))
|
||||
}
|
||||
|
||||
return sshKeywords, nil
|
||||
}
|
||||
|
||||
@@ -5168,9 +5168,9 @@ __metadata:
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"body-parser@npm:1.20.2":
|
||||
version: 1.20.2
|
||||
resolution: "body-parser@npm:1.20.2"
|
||||
"body-parser@npm:1.20.3":
|
||||
version: 1.20.3
|
||||
resolution: "body-parser@npm:1.20.3"
|
||||
dependencies:
|
||||
bytes: "npm:3.1.2"
|
||||
content-type: "npm:~1.0.5"
|
||||
@@ -5180,11 +5180,11 @@ __metadata:
|
||||
http-errors: "npm:2.0.0"
|
||||
iconv-lite: "npm:0.4.24"
|
||||
on-finished: "npm:2.4.1"
|
||||
qs: "npm:6.11.0"
|
||||
qs: "npm:6.13.0"
|
||||
raw-body: "npm:2.5.2"
|
||||
type-is: "npm:~1.6.18"
|
||||
unpipe: "npm:1.0.0"
|
||||
checksum: 10c0/06f1438fff388a2e2354c96aa3ea8147b79bfcb1262dfcc2aae68ec13723d01d5781680657b74e9f83c808266d5baf52804032fbde2b7382b89bd8cdb273ace9
|
||||
checksum: 10c0/0a9a93b7518f222885498dcecaad528cf010dd109b071bf471c93def4bfe30958b83e03496eb9c1ad4896db543d999bb62be1a3087294162a88cfa1b42c16310
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
@@ -5479,6 +5479,19 @@ __metadata:
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"call-bind@npm:^1.0.7":
|
||||
version: 1.0.7
|
||||
resolution: "call-bind@npm:1.0.7"
|
||||
dependencies:
|
||||
es-define-property: "npm:^1.0.0"
|
||||
es-errors: "npm:^1.3.0"
|
||||
function-bind: "npm:^1.1.2"
|
||||
get-intrinsic: "npm:^1.2.4"
|
||||
set-function-length: "npm:^1.2.1"
|
||||
checksum: 10c0/a3ded2e423b8e2a265983dba81c27e125b48eefb2655e7dfab6be597088da3d47c47976c24bc51b8fd9af1061f8f87b4ab78a314f3c77784b2ae2ba535ad8b8d
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"callsites@npm:^3.0.0":
|
||||
version: 3.1.0
|
||||
resolution: "callsites@npm:3.1.0"
|
||||
@@ -6281,7 +6294,7 @@ __metadata:
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"define-data-property@npm:^1.0.1":
|
||||
"define-data-property@npm:^1.0.1, define-data-property@npm:^1.1.4":
|
||||
version: 1.1.4
|
||||
resolution: "define-data-property@npm:1.1.4"
|
||||
dependencies:
|
||||
@@ -6732,6 +6745,13 @@ __metadata:
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"encodeurl@npm:~2.0.0":
|
||||
version: 2.0.0
|
||||
resolution: "encodeurl@npm:2.0.0"
|
||||
checksum: 10c0/5d317306acb13e6590e28e27924c754163946a2480de11865c991a3a7eed4315cd3fba378b543ca145829569eefe9b899f3d84bb09870f675ae60bc924b01ceb
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"encoding@npm:^0.1.13":
|
||||
version: 0.1.13
|
||||
resolution: "encoding@npm:0.1.13"
|
||||
@@ -6968,41 +6988,41 @@ __metadata:
|
||||
linkType: hard
|
||||
|
||||
"express@npm:^4.17.3":
|
||||
version: 4.19.2
|
||||
resolution: "express@npm:4.19.2"
|
||||
version: 4.21.0
|
||||
resolution: "express@npm:4.21.0"
|
||||
dependencies:
|
||||
accepts: "npm:~1.3.8"
|
||||
array-flatten: "npm:1.1.1"
|
||||
body-parser: "npm:1.20.2"
|
||||
body-parser: "npm:1.20.3"
|
||||
content-disposition: "npm:0.5.4"
|
||||
content-type: "npm:~1.0.4"
|
||||
cookie: "npm:0.6.0"
|
||||
cookie-signature: "npm:1.0.6"
|
||||
debug: "npm:2.6.9"
|
||||
depd: "npm:2.0.0"
|
||||
encodeurl: "npm:~1.0.2"
|
||||
encodeurl: "npm:~2.0.0"
|
||||
escape-html: "npm:~1.0.3"
|
||||
etag: "npm:~1.8.1"
|
||||
finalhandler: "npm:1.2.0"
|
||||
finalhandler: "npm:1.3.1"
|
||||
fresh: "npm:0.5.2"
|
||||
http-errors: "npm:2.0.0"
|
||||
merge-descriptors: "npm:1.0.1"
|
||||
merge-descriptors: "npm:1.0.3"
|
||||
methods: "npm:~1.1.2"
|
||||
on-finished: "npm:2.4.1"
|
||||
parseurl: "npm:~1.3.3"
|
||||
path-to-regexp: "npm:0.1.7"
|
||||
path-to-regexp: "npm:0.1.10"
|
||||
proxy-addr: "npm:~2.0.7"
|
||||
qs: "npm:6.11.0"
|
||||
qs: "npm:6.13.0"
|
||||
range-parser: "npm:~1.2.1"
|
||||
safe-buffer: "npm:5.2.1"
|
||||
send: "npm:0.18.0"
|
||||
serve-static: "npm:1.15.0"
|
||||
send: "npm:0.19.0"
|
||||
serve-static: "npm:1.16.2"
|
||||
setprototypeof: "npm:1.2.0"
|
||||
statuses: "npm:2.0.1"
|
||||
type-is: "npm:~1.6.18"
|
||||
utils-merge: "npm:1.0.1"
|
||||
vary: "npm:~1.1.2"
|
||||
checksum: 10c0/e82e2662ea9971c1407aea9fc3c16d6b963e55e3830cd0ef5e00b533feda8b770af4e3be630488ef8a752d7c75c4fcefb15892868eeaafe7353cb9e3e269fdcb
|
||||
checksum: 10c0/4cf7ca328f3fdeb720f30ccb2ea7708bfa7d345f9cc460b64a82bf1b2c91e5b5852ba15a9a11b2a165d6089acf83457fc477dc904d59cd71ed34c7a91762c6cc
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
@@ -7145,18 +7165,18 @@ __metadata:
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"finalhandler@npm:1.2.0":
|
||||
version: 1.2.0
|
||||
resolution: "finalhandler@npm:1.2.0"
|
||||
"finalhandler@npm:1.3.1":
|
||||
version: 1.3.1
|
||||
resolution: "finalhandler@npm:1.3.1"
|
||||
dependencies:
|
||||
debug: "npm:2.6.9"
|
||||
encodeurl: "npm:~1.0.2"
|
||||
encodeurl: "npm:~2.0.0"
|
||||
escape-html: "npm:~1.0.3"
|
||||
on-finished: "npm:2.4.1"
|
||||
parseurl: "npm:~1.3.3"
|
||||
statuses: "npm:2.0.1"
|
||||
unpipe: "npm:~1.0.0"
|
||||
checksum: 10c0/64b7e5ff2ad1fcb14931cd012651631b721ce657da24aedb5650ddde9378bf8e95daa451da43398123f5de161a81e79ff5affe4f9f2a6d2df4a813d6d3e254b7
|
||||
checksum: 10c0/d38035831865a49b5610206a3a9a9aae4e8523cbbcd01175d0480ffbf1278c47f11d89be3ca7f617ae6d94f29cf797546a4619cd84dd109009ef33f12f69019f
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
@@ -7669,7 +7689,7 @@ __metadata:
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"has-property-descriptors@npm:^1.0.0":
|
||||
"has-property-descriptors@npm:^1.0.0, has-property-descriptors@npm:^1.0.2":
|
||||
version: 1.0.2
|
||||
resolution: "has-property-descriptors@npm:1.0.2"
|
||||
dependencies:
|
||||
@@ -9184,10 +9204,10 @@ __metadata:
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"merge-descriptors@npm:1.0.1":
|
||||
version: 1.0.1
|
||||
resolution: "merge-descriptors@npm:1.0.1"
|
||||
checksum: 10c0/b67d07bd44cfc45cebdec349bb6e1f7b077ee2fd5beb15d1f7af073849208cb6f144fe403e29a36571baf3f4e86469ac39acf13c318381e958e186b2766f54ec
|
||||
"merge-descriptors@npm:1.0.3":
|
||||
version: 1.0.3
|
||||
resolution: "merge-descriptors@npm:1.0.3"
|
||||
checksum: 10c0/866b7094afd9293b5ea5dcd82d71f80e51514bed33b4c4e9f516795dc366612a4cbb4dc94356e943a8a6914889a914530badff27f397191b9b75cda20b6bae93
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
@@ -10124,6 +10144,13 @@ __metadata:
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"object-inspect@npm:^1.13.1":
|
||||
version: 1.13.2
|
||||
resolution: "object-inspect@npm:1.13.2"
|
||||
checksum: 10c0/b97835b4c91ec37b5fd71add84f21c3f1047d1d155d00c0fcd6699516c256d4fcc6ff17a1aced873197fe447f91a3964178fd2a67a1ee2120cdaf60e81a050b4
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"object-inspect@npm:^1.9.0":
|
||||
version: 1.13.1
|
||||
resolution: "object-inspect@npm:1.13.1"
|
||||
@@ -10452,10 +10479,10 @@ __metadata:
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"path-to-regexp@npm:0.1.7":
|
||||
version: 0.1.7
|
||||
resolution: "path-to-regexp@npm:0.1.7"
|
||||
checksum: 10c0/50a1ddb1af41a9e68bd67ca8e331a705899d16fb720a1ea3a41e310480948387daf603abb14d7b0826c58f10146d49050a1291ba6a82b78a382d1c02c0b8f905
|
||||
"path-to-regexp@npm:0.1.10":
|
||||
version: 0.1.10
|
||||
resolution: "path-to-regexp@npm:0.1.10"
|
||||
checksum: 10c0/34196775b9113ca6df88e94c8d83ba82c0e1a2063dd33bfe2803a980da8d49b91db8104f49d5191b44ea780d46b8670ce2b7f4a5e349b0c48c6779b653f1afe4
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
@@ -10740,12 +10767,12 @@ __metadata:
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"qs@npm:6.11.0":
|
||||
version: 6.11.0
|
||||
resolution: "qs@npm:6.11.0"
|
||||
"qs@npm:6.13.0":
|
||||
version: 6.13.0
|
||||
resolution: "qs@npm:6.13.0"
|
||||
dependencies:
|
||||
side-channel: "npm:^1.0.4"
|
||||
checksum: 10c0/4e4875e4d7c7c31c233d07a448e7e4650f456178b9dd3766b7cfa13158fdb24ecb8c4f059fa91e820dc6ab9f2d243721d071c9c0378892dcdad86e9e9a27c68f
|
||||
side-channel: "npm:^1.0.6"
|
||||
checksum: 10c0/62372cdeec24dc83a9fb240b7533c0fdcf0c5f7e0b83343edd7310f0ab4c8205a5e7c56406531f2e47e1b4878a3821d652be4192c841de5b032ca83619d8f860
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
@@ -11450,9 +11477,9 @@ __metadata:
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"send@npm:0.18.0":
|
||||
version: 0.18.0
|
||||
resolution: "send@npm:0.18.0"
|
||||
"send@npm:0.19.0":
|
||||
version: 0.19.0
|
||||
resolution: "send@npm:0.19.0"
|
||||
dependencies:
|
||||
debug: "npm:2.6.9"
|
||||
depd: "npm:2.0.0"
|
||||
@@ -11467,7 +11494,7 @@ __metadata:
|
||||
on-finished: "npm:2.4.1"
|
||||
range-parser: "npm:~1.2.1"
|
||||
statuses: "npm:2.0.1"
|
||||
checksum: 10c0/0eb134d6a51fc13bbcb976a1f4214ea1e33f242fae046efc311e80aff66c7a43603e26a79d9d06670283a13000e51be6e0a2cb80ff0942eaf9f1cd30b7ae736a
|
||||
checksum: 10c0/ea3f8a67a8f0be3d6bf9080f0baed6d2c51d11d4f7b4470de96a5029c598a7011c497511ccc28968b70ef05508675cebff27da9151dd2ceadd60be4e6cf845e3
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
@@ -11504,15 +11531,15 @@ __metadata:
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"serve-static@npm:1.15.0":
|
||||
version: 1.15.0
|
||||
resolution: "serve-static@npm:1.15.0"
|
||||
"serve-static@npm:1.16.2":
|
||||
version: 1.16.2
|
||||
resolution: "serve-static@npm:1.16.2"
|
||||
dependencies:
|
||||
encodeurl: "npm:~1.0.2"
|
||||
encodeurl: "npm:~2.0.0"
|
||||
escape-html: "npm:~1.0.3"
|
||||
parseurl: "npm:~1.3.3"
|
||||
send: "npm:0.18.0"
|
||||
checksum: 10c0/fa9f0e21a540a28f301258dfe1e57bb4f81cd460d28f0e973860477dd4acef946a1f41748b5bd41c73b621bea2029569c935faa38578fd34cd42a9b4947088ba
|
||||
send: "npm:0.19.0"
|
||||
checksum: 10c0/528fff6f5e12d0c5a391229ad893910709bc51b5705962b09404a1d813857578149b8815f35d3ee5752f44cd378d0f31669d4b1d7e2d11f41e08283d5134bd1f
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
@@ -11535,6 +11562,20 @@ __metadata:
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"set-function-length@npm:^1.2.1":
|
||||
version: 1.2.2
|
||||
resolution: "set-function-length@npm:1.2.2"
|
||||
dependencies:
|
||||
define-data-property: "npm:^1.1.4"
|
||||
es-errors: "npm:^1.3.0"
|
||||
function-bind: "npm:^1.1.2"
|
||||
get-intrinsic: "npm:^1.2.4"
|
||||
gopd: "npm:^1.0.1"
|
||||
has-property-descriptors: "npm:^1.0.2"
|
||||
checksum: 10c0/82850e62f412a258b71e123d4ed3873fa9377c216809551192bb6769329340176f109c2eeae8c22a8d386c76739855f78e8716515c818bcaef384b51110f0f3c
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"setprototypeof@npm:1.1.0":
|
||||
version: 1.1.0
|
||||
resolution: "setprototypeof@npm:1.1.0"
|
||||
@@ -11592,6 +11633,18 @@ __metadata:
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"side-channel@npm:^1.0.6":
|
||||
version: 1.0.6
|
||||
resolution: "side-channel@npm:1.0.6"
|
||||
dependencies:
|
||||
call-bind: "npm:^1.0.7"
|
||||
es-errors: "npm:^1.3.0"
|
||||
get-intrinsic: "npm:^1.2.4"
|
||||
object-inspect: "npm:^1.13.1"
|
||||
checksum: 10c0/d2afd163dc733cc0a39aa6f7e39bf0c436293510dbccbff446733daeaf295857dbccf94297092ec8c53e2503acac30f0b78830876f0485991d62a90e9cad305f
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"signal-exit@npm:^3.0.2, signal-exit@npm:^3.0.3, signal-exit@npm:^3.0.7":
|
||||
version: 3.0.7
|
||||
resolution: "signal-exit@npm:3.0.7"
|
||||
|
||||
Reference in New Issue
Block a user