Skip to main content
Deno 2 is finally here 🎉️
Learn more

DFtpS - Deno Ftp Server

logo deno doc

DFtpS is an FTP server based on ftp-srv with Deno.

Usage

Install

curl -fsSL https://deno.land/x/dftps/install.sh | sh

Install Specific Version

curl -fsSL https://deno.land/x/dftps/install.sh | sh -s v1.0.0

Make your own

Simple

  • First, we import the Server class and type for user authentication.
import { Server } from "https://deno.land/x/dftps/server/mod.ts";
import type { UsernameResolvable, LoginResolvable } from "https://deno.land/x/dftps/server/connection.ts";
const serve = new Server({ port: 21, hostname: "127.0.0.1" });
  • All we have to do is wait for a new connection and check the veracity of it using the authentication tools (awaitUsername, awaitLogin).
for await (const connection of serve) {
  const { awaitUsername, awaitLogin } = connection;
  /** waiting to receiving username from connection */
  awaitUsername.then(({ username, resolveUsername }: UsernameResolvable) => {
    if (!username !== "my-username") return resolveUsername.reject("Incorrect username!");
    resolveUsername.resolve();
  });
  /** waiting to receiving password from connection and finalize the user authenticate */
  awaitLogin.then(({ password, resolvePassword }: LoginResolvable) => {
    if (password !== "my-password") return resolvePassword.reject("Wrong password!");
    resolvePassword.resolve({ root: "my-folder", uid: 1000, gid: 1000 });
  });
}

With database

  • To begin we will initially import the “createDb” function which will allow us to create a database and the “Users” model in addition to the imports mentioned above.

    import { verify, Model } from "https://deno.land/x/dftps/deps.ts";
    import createDb from "https://deno.land/x/dftps/src/db/mod.ts";
    import Users from "https://deno.land/x/dftps/src/db/Users.ts";
  • Only the following database types are supported: “MariaDB” | “MongoDB” | “MySQL” | “PostgreSQL” | “SQLite”

    • Maria, MySQL, PostgreSQL Options
      • database [string] (Required)
      • host [string] (Required)
      • username [string] (Required)
      • password [string] (Required)
      • port [number] (Optional)
    • MongoDB Options
      • uri [string] (Required)
      • database [string] (Required)
    • SQLite Options
      • filepath [string] (Required)
/** Example with MongoDB */
await createDb({
  connector: "MongoDB",
  uri: 'mongodb://127.0.0.1:27017',
  database: 'test'
});

const serve = new Server(ListenOptions, FTPServerOptions);

for await (const connection of serve) {
  const { awaitUsername, awaitLogin } = connection;
  let user: Model;
  /** Waiting to receiving username from connection */
  awaitUsername.then(({ username, resolveUsername }: UsernameResolvable) => {
    /** Find user in database */
    const found = await Users.where('username', username).get();
    if ((found instanceof Array && found.length === 0) || !found) return resolveUsername.reject("Incorrect username!");
    user = (found instanceof Array) ? found[0] : found;
    resolveUsername.resolve();
  });
  /** Waiting to receiving password from connection and finalize the user authenticate */
  awaitLogin.then(async ({ password, resolvePassword }: LoginResolvable) => {
    if (!user) return resolvePassword.reject("User not found!");
    if (! await verify(password, (user.password as string))) return resolvePassword.reject("Wrong password!");
    const { root, uid, gid } = user;
    resolvePassword.resolve({ root: (root as string), uid: (uid as number), gid: (gid as number) });
  });
}

Log example

output_example


Deno Dependencies

List of FTP commands

See COMMANDS.md

Contributing

See CONTRIBUTING.md

References