ajout de l'upload. Reste un mystérieux problème à régler avec l'extenstion et multer
This commit is contained in:
@@ -9,3 +9,6 @@
|
|||||||
!api_back/*.html
|
!api_back/*.html
|
||||||
!api_back/*.lock
|
!api_back/*.lock
|
||||||
!api_back/.env
|
!api_back/.env
|
||||||
|
!api_back/src/uploads/avatars/default.png
|
||||||
|
!api_back/*.jpg
|
||||||
|
!api_back/*.jpeg
|
||||||
|
|||||||
@@ -5,6 +5,7 @@ WORKDIR /usr/app
|
|||||||
COPY api_back/* .
|
COPY api_back/* .
|
||||||
COPY api_back/.env .env
|
COPY api_back/.env .env
|
||||||
|
|
||||||
|
|
||||||
RUN npm ci
|
RUN npm ci
|
||||||
|
|
||||||
CMD [ "npm", "run", "start:dev" ]
|
CMD [ "npm", "run", "start:dev" ]
|
||||||
|
|||||||
9
srcs/requirements/nestjs/api_back/node_modules/.package-lock.json
generated
vendored
9
srcs/requirements/nestjs/api_back/node_modules/.package-lock.json
generated
vendored
@@ -2207,6 +2207,15 @@
|
|||||||
"resolved": "https://registry.npmjs.org/@types/mime/-/mime-3.0.1.tgz",
|
"resolved": "https://registry.npmjs.org/@types/mime/-/mime-3.0.1.tgz",
|
||||||
"integrity": "sha512-Y4XFY5VJAuw0FgAqPNd6NNoV44jbq9Bz2L7Rh/J6jLTiHBSBJa9fxqQIvkIld4GsoDOcCbvzOUAbLPsSKKg+uA=="
|
"integrity": "sha512-Y4XFY5VJAuw0FgAqPNd6NNoV44jbq9Bz2L7Rh/J6jLTiHBSBJa9fxqQIvkIld4GsoDOcCbvzOUAbLPsSKKg+uA=="
|
||||||
},
|
},
|
||||||
|
"node_modules/@types/multer": {
|
||||||
|
"version": "1.4.7",
|
||||||
|
"resolved": "https://registry.npmjs.org/@types/multer/-/multer-1.4.7.tgz",
|
||||||
|
"integrity": "sha512-/SNsDidUFCvqqcWDwxv2feww/yqhNeTRL5CVoL3jU4Goc4kKEL10T7Eye65ZqPNi4HRx8sAEX59pV1aEH7drNA==",
|
||||||
|
"dev": true,
|
||||||
|
"dependencies": {
|
||||||
|
"@types/express": "*"
|
||||||
|
}
|
||||||
|
},
|
||||||
"node_modules/@types/node": {
|
"node_modules/@types/node": {
|
||||||
"version": "16.11.68",
|
"version": "16.11.68",
|
||||||
"resolved": "https://registry.npmjs.org/@types/node/-/node-16.11.68.tgz",
|
"resolved": "https://registry.npmjs.org/@types/node/-/node-16.11.68.tgz",
|
||||||
|
|||||||
21
srcs/requirements/nestjs/api_back/node_modules/@types/multer/LICENSE
generated
vendored
Executable file
21
srcs/requirements/nestjs/api_back/node_modules/@types/multer/LICENSE
generated
vendored
Executable file
@@ -0,0 +1,21 @@
|
|||||||
|
MIT License
|
||||||
|
|
||||||
|
Copyright (c) Microsoft Corporation.
|
||||||
|
|
||||||
|
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
|
of this software and associated documentation files (the "Software"), to deal
|
||||||
|
in the Software without restriction, including without limitation the rights
|
||||||
|
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||||
|
copies of the Software, and to permit persons to whom the Software is
|
||||||
|
furnished to do so, subject to the following conditions:
|
||||||
|
|
||||||
|
The above copyright notice and this permission notice shall be included in all
|
||||||
|
copies or substantial portions of the Software.
|
||||||
|
|
||||||
|
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
|
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||||
|
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||||
|
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||||
|
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||||
|
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||||
|
SOFTWARE
|
||||||
16
srcs/requirements/nestjs/api_back/node_modules/@types/multer/README.md
generated
vendored
Executable file
16
srcs/requirements/nestjs/api_back/node_modules/@types/multer/README.md
generated
vendored
Executable file
@@ -0,0 +1,16 @@
|
|||||||
|
# Installation
|
||||||
|
> `npm install --save @types/multer`
|
||||||
|
|
||||||
|
# Summary
|
||||||
|
This package contains type definitions for multer (https://github.com/expressjs/multer).
|
||||||
|
|
||||||
|
# Details
|
||||||
|
Files were exported from https://github.com/DefinitelyTyped/DefinitelyTyped/tree/master/types/multer.
|
||||||
|
|
||||||
|
### Additional Details
|
||||||
|
* Last updated: Wed, 07 Jul 2021 00:01:45 GMT
|
||||||
|
* Dependencies: [@types/express](https://npmjs.com/package/@types/express)
|
||||||
|
* Global values: none
|
||||||
|
|
||||||
|
# Credits
|
||||||
|
These definitions were written by [jt000](https://github.com/jt000), [vilicvane](https://github.com/vilic), [David Broder-Rodgers](https://github.com/DavidBR-SW), [Michael Ledin](https://github.com/mxl), [HyunSeob Lee](https://github.com/hyunseob), [Pierre Tchuente](https://github.com/PierreTchuente), [Oliver Emery](https://github.com/thrymgjol), and [Piotr Błażejewicz](https://github.com/peterblazejewicz).
|
||||||
321
srcs/requirements/nestjs/api_back/node_modules/@types/multer/index.d.ts
generated
vendored
Executable file
321
srcs/requirements/nestjs/api_back/node_modules/@types/multer/index.d.ts
generated
vendored
Executable file
@@ -0,0 +1,321 @@
|
|||||||
|
// Type definitions for multer 1.4
|
||||||
|
// Project: https://github.com/expressjs/multer
|
||||||
|
// Definitions by: jt000 <https://github.com/jt000>
|
||||||
|
// vilicvane <https://github.com/vilic>
|
||||||
|
// David Broder-Rodgers <https://github.com/DavidBR-SW>
|
||||||
|
// Michael Ledin <https://github.com/mxl>
|
||||||
|
// HyunSeob Lee <https://github.com/hyunseob>
|
||||||
|
// Pierre Tchuente <https://github.com/PierreTchuente>
|
||||||
|
// Oliver Emery <https://github.com/thrymgjol>
|
||||||
|
// Piotr Błażejewicz <https://github.com/peterblazejewicz>
|
||||||
|
// Definitions: https://github.com/DefinitelyTyped/DefinitelyTyped
|
||||||
|
import { Request, RequestHandler } from 'express';
|
||||||
|
import { Readable } from 'stream';
|
||||||
|
|
||||||
|
declare global {
|
||||||
|
namespace Express {
|
||||||
|
namespace Multer {
|
||||||
|
/** Object containing file metadata and access information. */
|
||||||
|
interface File {
|
||||||
|
/** Name of the form field associated with this file. */
|
||||||
|
fieldname: string;
|
||||||
|
/** Name of the file on the uploader's computer. */
|
||||||
|
originalname: string;
|
||||||
|
/**
|
||||||
|
* Value of the `Content-Transfer-Encoding` header for this file.
|
||||||
|
* @deprecated since July 2015
|
||||||
|
* @see RFC 7578, Section 4.7
|
||||||
|
*/
|
||||||
|
encoding: string;
|
||||||
|
/** Value of the `Content-Type` header for this file. */
|
||||||
|
mimetype: string;
|
||||||
|
/** Size of the file in bytes. */
|
||||||
|
size: number;
|
||||||
|
/**
|
||||||
|
* A readable stream of this file. Only available to the `_handleFile`
|
||||||
|
* callback for custom `StorageEngine`s.
|
||||||
|
*/
|
||||||
|
stream: Readable;
|
||||||
|
/** `DiskStorage` only: Directory to which this file has been uploaded. */
|
||||||
|
destination: string;
|
||||||
|
/** `DiskStorage` only: Name of this file within `destination`. */
|
||||||
|
filename: string;
|
||||||
|
/** `DiskStorage` only: Full path to the uploaded file. */
|
||||||
|
path: string;
|
||||||
|
/** `MemoryStorage` only: A Buffer containing the entire file. */
|
||||||
|
buffer: Buffer;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
interface Request {
|
||||||
|
/** `Multer.File` object populated by `single()` middleware. */
|
||||||
|
file?: Multer.File | undefined;
|
||||||
|
/**
|
||||||
|
* Array or dictionary of `Multer.File` object populated by `array()`,
|
||||||
|
* `fields()`, and `any()` middleware.
|
||||||
|
*/
|
||||||
|
files?: {
|
||||||
|
[fieldname: string]: Multer.File[];
|
||||||
|
} | Multer.File[] | undefined;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns a Multer instance that provides several methods for generating
|
||||||
|
* middleware that process files uploaded in `multipart/form-data` format.
|
||||||
|
*
|
||||||
|
* The `StorageEngine` specified in `storage` will be used to store files. If
|
||||||
|
* `storage` is not set and `dest` is, files will be stored in `dest` on the
|
||||||
|
* local file system with random names. If neither are set, files will be stored
|
||||||
|
* in memory.
|
||||||
|
*
|
||||||
|
* In addition to files, all generated middleware process all text fields in
|
||||||
|
* the request. For each non-file field, the `Request.body` object will be
|
||||||
|
* populated with an entry mapping the field name to its string value, or array
|
||||||
|
* of string values if multiple fields share the same name.
|
||||||
|
*/
|
||||||
|
declare function multer(options?: multer.Options): multer.Multer;
|
||||||
|
|
||||||
|
declare namespace multer {
|
||||||
|
/**
|
||||||
|
* @see {@link https://github.com/expressjs/multer#api}
|
||||||
|
*/
|
||||||
|
interface Multer {
|
||||||
|
/**
|
||||||
|
* Returns middleware that processes a single file associated with the
|
||||||
|
* given form field.
|
||||||
|
*
|
||||||
|
* The `Request` object will be populated with a `file` object containing
|
||||||
|
* information about the processed file.
|
||||||
|
*
|
||||||
|
* @param fieldName Name of the multipart form field to process.
|
||||||
|
*/
|
||||||
|
single(fieldName: string): RequestHandler;
|
||||||
|
/**
|
||||||
|
* Returns middleware that processes multiple files sharing the same field
|
||||||
|
* name.
|
||||||
|
*
|
||||||
|
* The `Request` object will be populated with a `files` array containing
|
||||||
|
* an information object for each processed file.
|
||||||
|
*
|
||||||
|
* @param fieldName Shared name of the multipart form fields to process.
|
||||||
|
* @param maxCount Optional. Maximum number of files to process. (default: Infinity)
|
||||||
|
* @throws `MulterError('LIMIT_UNEXPECTED_FILE')` if more than `maxCount` files are associated with `fieldName`
|
||||||
|
*/
|
||||||
|
array(fieldName: string, maxCount?: number): RequestHandler;
|
||||||
|
/**
|
||||||
|
* Returns middleware that processes multiple files associated with the
|
||||||
|
* given form fields.
|
||||||
|
*
|
||||||
|
* The `Request` object will be populated with a `files` object which
|
||||||
|
* maps each field name to an array of the associated file information
|
||||||
|
* objects.
|
||||||
|
*
|
||||||
|
* @param fields Array of `Field` objects describing multipart form fields to process.
|
||||||
|
* @throws `MulterError('LIMIT_UNEXPECTED_FILE')` if more than `maxCount` files are associated with `fieldName` for any field.
|
||||||
|
*/
|
||||||
|
fields(fields: ReadonlyArray<Field>): RequestHandler;
|
||||||
|
/**
|
||||||
|
* Returns middleware that processes all files contained in the multipart
|
||||||
|
* request.
|
||||||
|
*
|
||||||
|
* The `Request` object will be populated with a `files` array containing
|
||||||
|
* an information object for each processed file.
|
||||||
|
*/
|
||||||
|
any(): RequestHandler;
|
||||||
|
/**
|
||||||
|
* Returns middleware that accepts only non-file multipart form fields.
|
||||||
|
*
|
||||||
|
* @throws `MulterError('LIMIT_UNEXPECTED_FILE')` if any file is encountered.
|
||||||
|
*/
|
||||||
|
none(): RequestHandler;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns a `StorageEngine` implementation configured to store files on
|
||||||
|
* the local file system.
|
||||||
|
*
|
||||||
|
* A string or function may be specified to determine the destination
|
||||||
|
* directory, and a function to determine filenames. If no options are set,
|
||||||
|
* files will be stored in the system's temporary directory with random 32
|
||||||
|
* character filenames.
|
||||||
|
*/
|
||||||
|
function diskStorage(options: DiskStorageOptions): StorageEngine;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns a `StorageEngine` implementation configured to store files in
|
||||||
|
* memory as `Buffer` objects.
|
||||||
|
*/
|
||||||
|
function memoryStorage(): StorageEngine;
|
||||||
|
|
||||||
|
type ErrorCode =
|
||||||
|
| 'LIMIT_PART_COUNT'
|
||||||
|
| 'LIMIT_FILE_SIZE'
|
||||||
|
| 'LIMIT_FILE_COUNT'
|
||||||
|
| 'LIMIT_FIELD_KEY'
|
||||||
|
| 'LIMIT_FIELD_VALUE'
|
||||||
|
| 'LIMIT_FIELD_COUNT'
|
||||||
|
| 'LIMIT_UNEXPECTED_FILE';
|
||||||
|
|
||||||
|
class MulterError extends Error {
|
||||||
|
constructor(code: ErrorCode, field?: string);
|
||||||
|
/** Name of the MulterError constructor. */
|
||||||
|
name: string;
|
||||||
|
/** Identifying error code. */
|
||||||
|
code: ErrorCode;
|
||||||
|
/** Descriptive error message. */
|
||||||
|
message: string;
|
||||||
|
/** Name of the multipart form field associated with this error. */
|
||||||
|
field?: string | undefined;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* a function to control which files should be uploaded and which should be skipped
|
||||||
|
* pass a boolean to indicate if the file should be accepted
|
||||||
|
* pass an error if something goes wrong
|
||||||
|
*/
|
||||||
|
interface FileFilterCallback {
|
||||||
|
(error: Error): void;
|
||||||
|
(error: null, acceptFile: boolean): void;
|
||||||
|
}
|
||||||
|
|
||||||
|
/** Options for initializing a Multer instance. */
|
||||||
|
interface Options {
|
||||||
|
/**
|
||||||
|
* A `StorageEngine` responsible for processing files uploaded via Multer.
|
||||||
|
* Takes precedence over `dest`.
|
||||||
|
*/
|
||||||
|
storage?: StorageEngine | undefined;
|
||||||
|
/**
|
||||||
|
* The destination directory for uploaded files. If `storage` is not set
|
||||||
|
* and `dest` is, Multer will create a `DiskStorage` instance configured
|
||||||
|
* to store files at `dest` with random filenames.
|
||||||
|
*
|
||||||
|
* Ignored if `storage` is set.
|
||||||
|
*/
|
||||||
|
dest?: string | undefined;
|
||||||
|
/**
|
||||||
|
* An object specifying various limits on incoming data. This object is
|
||||||
|
* passed to Busboy directly, and the details of properties can be found
|
||||||
|
* at https://github.com/mscdex/busboy#busboy-methods.
|
||||||
|
*/
|
||||||
|
limits?: {
|
||||||
|
/** Maximum size of each form field name in bytes. (Default: 100) */
|
||||||
|
fieldNameSize?: number | undefined;
|
||||||
|
/** Maximum size of each form field value in bytes. (Default: 1048576) */
|
||||||
|
fieldSize?: number | undefined;
|
||||||
|
/** Maximum number of non-file form fields. (Default: Infinity) */
|
||||||
|
fields?: number | undefined;
|
||||||
|
/** Maximum size of each file in bytes. (Default: Infinity) */
|
||||||
|
fileSize?: number | undefined;
|
||||||
|
/** Maximum number of file fields. (Default: Infinity) */
|
||||||
|
files?: number | undefined;
|
||||||
|
/** Maximum number of parts (non-file fields + files). (Default: Infinity) */
|
||||||
|
parts?: number | undefined;
|
||||||
|
/** Maximum number of headers. (Default: 2000) */
|
||||||
|
headerPairs?: number | undefined;
|
||||||
|
} | undefined;
|
||||||
|
/** Preserve the full path of the original filename rather than the basename. (Default: false) */
|
||||||
|
preservePath?: boolean | undefined;
|
||||||
|
/**
|
||||||
|
* Optional function to control which files are uploaded. This is called
|
||||||
|
* for every file that is processed.
|
||||||
|
*
|
||||||
|
* @param req The Express `Request` object.
|
||||||
|
* @param file Object containing information about the processed file.
|
||||||
|
* @param callback a function to control which files should be uploaded and which should be skipped.
|
||||||
|
*/
|
||||||
|
fileFilter?(
|
||||||
|
req: Request,
|
||||||
|
file: Express.Multer.File,
|
||||||
|
callback: FileFilterCallback,
|
||||||
|
): void;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Implementations of this interface are responsible for storing files
|
||||||
|
* encountered by Multer and returning information on how to access them
|
||||||
|
* once stored. Implementations must also provide a method for removing
|
||||||
|
* files in the event that an error occurs.
|
||||||
|
*/
|
||||||
|
interface StorageEngine {
|
||||||
|
/**
|
||||||
|
* Store the file described by `file`, then invoke the callback with
|
||||||
|
* information about the stored file.
|
||||||
|
*
|
||||||
|
* File contents are available as a stream via `file.stream`. Information
|
||||||
|
* passed to the callback will be merged with `file` for subsequent
|
||||||
|
* middleware.
|
||||||
|
*
|
||||||
|
* @param req The Express `Request` object.
|
||||||
|
* @param file Object with `stream`, `fieldname`, `originalname`, `encoding`, and `mimetype` defined.
|
||||||
|
* @param callback Callback to specify file information.
|
||||||
|
*/
|
||||||
|
_handleFile(
|
||||||
|
req: Request,
|
||||||
|
file: Express.Multer.File,
|
||||||
|
callback: (error?: any, info?: Partial<Express.Multer.File>) => void
|
||||||
|
): void;
|
||||||
|
/**
|
||||||
|
* Remove the file described by `file`, then invoke the callback with.
|
||||||
|
*
|
||||||
|
* `file` contains all the properties available to `_handleFile`, as
|
||||||
|
* well as those returned by `_handleFile`.
|
||||||
|
*
|
||||||
|
* @param req The Express `Request` object.
|
||||||
|
* @param file Object containing information about the processed file.
|
||||||
|
* @param callback Callback to indicate completion.
|
||||||
|
*/
|
||||||
|
_removeFile(
|
||||||
|
req: Request,
|
||||||
|
file: Express.Multer.File,
|
||||||
|
callback: (error: Error | null) => void
|
||||||
|
): void;
|
||||||
|
}
|
||||||
|
|
||||||
|
interface DiskStorageOptions {
|
||||||
|
/**
|
||||||
|
* A string or function that determines the destination path for uploaded
|
||||||
|
* files. If a string is passed and the directory does not exist, Multer
|
||||||
|
* attempts to create it recursively. If neither a string or a function
|
||||||
|
* is passed, the destination defaults to `os.tmpdir()`.
|
||||||
|
*
|
||||||
|
* @param req The Express `Request` object.
|
||||||
|
* @param file Object containing information about the processed file.
|
||||||
|
* @param callback Callback to determine the destination path.
|
||||||
|
*/
|
||||||
|
destination?: string | ((
|
||||||
|
req: Request,
|
||||||
|
file: Express.Multer.File,
|
||||||
|
callback: (error: Error | null, destination: string) => void
|
||||||
|
) => void) | undefined;
|
||||||
|
/**
|
||||||
|
* A function that determines the name of the uploaded file. If nothing
|
||||||
|
* is passed, Multer will generate a 32 character pseudorandom hex string
|
||||||
|
* with no extension.
|
||||||
|
*
|
||||||
|
* @param req The Express `Request` object.
|
||||||
|
* @param file Object containing information about the processed file.
|
||||||
|
* @param callback Callback to determine the name of the uploaded file.
|
||||||
|
*/
|
||||||
|
filename?(
|
||||||
|
req: Request,
|
||||||
|
file: Express.Multer.File,
|
||||||
|
callback: (error: Error | null, filename: string) => void
|
||||||
|
): void;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* An object describing a field name and the maximum number of files with
|
||||||
|
* that field name to accept.
|
||||||
|
*/
|
||||||
|
interface Field {
|
||||||
|
/** The field name. */
|
||||||
|
name: string;
|
||||||
|
/** Optional maximum number of files per field to accept. (Default: Infinity) */
|
||||||
|
maxCount?: number | undefined;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
export = multer;
|
||||||
62
srcs/requirements/nestjs/api_back/node_modules/@types/multer/package.json
generated
vendored
Executable file
62
srcs/requirements/nestjs/api_back/node_modules/@types/multer/package.json
generated
vendored
Executable file
@@ -0,0 +1,62 @@
|
|||||||
|
{
|
||||||
|
"name": "@types/multer",
|
||||||
|
"version": "1.4.7",
|
||||||
|
"description": "TypeScript definitions for multer",
|
||||||
|
"homepage": "https://github.com/DefinitelyTyped/DefinitelyTyped/tree/master/types/multer",
|
||||||
|
"license": "MIT",
|
||||||
|
"contributors": [
|
||||||
|
{
|
||||||
|
"name": "jt000",
|
||||||
|
"url": "https://github.com/jt000",
|
||||||
|
"githubUsername": "jt000"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "vilicvane",
|
||||||
|
"url": "https://github.com/vilic",
|
||||||
|
"githubUsername": "vilic"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "David Broder-Rodgers",
|
||||||
|
"url": "https://github.com/DavidBR-SW",
|
||||||
|
"githubUsername": "DavidBR-SW"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "Michael Ledin",
|
||||||
|
"url": "https://github.com/mxl",
|
||||||
|
"githubUsername": "mxl"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "HyunSeob Lee",
|
||||||
|
"url": "https://github.com/hyunseob",
|
||||||
|
"githubUsername": "hyunseob"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "Pierre Tchuente",
|
||||||
|
"url": "https://github.com/PierreTchuente",
|
||||||
|
"githubUsername": "PierreTchuente"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "Oliver Emery",
|
||||||
|
"url": "https://github.com/thrymgjol",
|
||||||
|
"githubUsername": "thrymgjol"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "Piotr Błażejewicz",
|
||||||
|
"url": "https://github.com/peterblazejewicz",
|
||||||
|
"githubUsername": "peterblazejewicz"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"main": "",
|
||||||
|
"types": "index.d.ts",
|
||||||
|
"repository": {
|
||||||
|
"type": "git",
|
||||||
|
"url": "https://github.com/DefinitelyTyped/DefinitelyTyped.git",
|
||||||
|
"directory": "types/multer"
|
||||||
|
},
|
||||||
|
"scripts": {},
|
||||||
|
"dependencies": {
|
||||||
|
"@types/express": "*"
|
||||||
|
},
|
||||||
|
"typesPublisherContentHash": "32b2d0cc5d84f278945858a1be2b00bcdd046da7c6e0886d5afd0d1e002ee95a",
|
||||||
|
"typeScriptVersion": "3.6"
|
||||||
|
}
|
||||||
22
srcs/requirements/nestjs/api_back/package-lock.json
generated
22
srcs/requirements/nestjs/api_back/package-lock.json
generated
@@ -37,7 +37,8 @@
|
|||||||
"reflect-metadata": "^0.1.13",
|
"reflect-metadata": "^0.1.13",
|
||||||
"rimraf": "^3.0.2",
|
"rimraf": "^3.0.2",
|
||||||
"rxjs": "^7.2.0",
|
"rxjs": "^7.2.0",
|
||||||
"typeorm": "^0.3.10"
|
"typeorm": "^0.3.10",
|
||||||
|
"uuid": "^9.0.0"
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"@nestjs/cli": "^9.0.0",
|
"@nestjs/cli": "^9.0.0",
|
||||||
@@ -45,6 +46,7 @@
|
|||||||
"@nestjs/testing": "^9.0.0",
|
"@nestjs/testing": "^9.0.0",
|
||||||
"@types/express": "^4.17.13",
|
"@types/express": "^4.17.13",
|
||||||
"@types/jest": "28.1.8",
|
"@types/jest": "28.1.8",
|
||||||
|
"@types/multer": "^1.4.7",
|
||||||
"@types/node": "^16.0.0",
|
"@types/node": "^16.0.0",
|
||||||
"@types/passport-jwt": "^3.0.7",
|
"@types/passport-jwt": "^3.0.7",
|
||||||
"@types/passport-local": "^1.0.34",
|
"@types/passport-local": "^1.0.34",
|
||||||
@@ -2268,6 +2270,15 @@
|
|||||||
"resolved": "https://registry.npmjs.org/@types/mime/-/mime-3.0.1.tgz",
|
"resolved": "https://registry.npmjs.org/@types/mime/-/mime-3.0.1.tgz",
|
||||||
"integrity": "sha512-Y4XFY5VJAuw0FgAqPNd6NNoV44jbq9Bz2L7Rh/J6jLTiHBSBJa9fxqQIvkIld4GsoDOcCbvzOUAbLPsSKKg+uA=="
|
"integrity": "sha512-Y4XFY5VJAuw0FgAqPNd6NNoV44jbq9Bz2L7Rh/J6jLTiHBSBJa9fxqQIvkIld4GsoDOcCbvzOUAbLPsSKKg+uA=="
|
||||||
},
|
},
|
||||||
|
"node_modules/@types/multer": {
|
||||||
|
"version": "1.4.7",
|
||||||
|
"resolved": "https://registry.npmjs.org/@types/multer/-/multer-1.4.7.tgz",
|
||||||
|
"integrity": "sha512-/SNsDidUFCvqqcWDwxv2feww/yqhNeTRL5CVoL3jU4Goc4kKEL10T7Eye65ZqPNi4HRx8sAEX59pV1aEH7drNA==",
|
||||||
|
"dev": true,
|
||||||
|
"dependencies": {
|
||||||
|
"@types/express": "*"
|
||||||
|
}
|
||||||
|
},
|
||||||
"node_modules/@types/node": {
|
"node_modules/@types/node": {
|
||||||
"version": "16.11.68",
|
"version": "16.11.68",
|
||||||
"resolved": "https://registry.npmjs.org/@types/node/-/node-16.11.68.tgz",
|
"resolved": "https://registry.npmjs.org/@types/node/-/node-16.11.68.tgz",
|
||||||
@@ -11422,6 +11433,15 @@
|
|||||||
"resolved": "https://registry.npmjs.org/@types/mime/-/mime-3.0.1.tgz",
|
"resolved": "https://registry.npmjs.org/@types/mime/-/mime-3.0.1.tgz",
|
||||||
"integrity": "sha512-Y4XFY5VJAuw0FgAqPNd6NNoV44jbq9Bz2L7Rh/J6jLTiHBSBJa9fxqQIvkIld4GsoDOcCbvzOUAbLPsSKKg+uA=="
|
"integrity": "sha512-Y4XFY5VJAuw0FgAqPNd6NNoV44jbq9Bz2L7Rh/J6jLTiHBSBJa9fxqQIvkIld4GsoDOcCbvzOUAbLPsSKKg+uA=="
|
||||||
},
|
},
|
||||||
|
"@types/multer": {
|
||||||
|
"version": "1.4.7",
|
||||||
|
"resolved": "https://registry.npmjs.org/@types/multer/-/multer-1.4.7.tgz",
|
||||||
|
"integrity": "sha512-/SNsDidUFCvqqcWDwxv2feww/yqhNeTRL5CVoL3jU4Goc4kKEL10T7Eye65ZqPNi4HRx8sAEX59pV1aEH7drNA==",
|
||||||
|
"dev": true,
|
||||||
|
"requires": {
|
||||||
|
"@types/express": "*"
|
||||||
|
}
|
||||||
|
},
|
||||||
"@types/node": {
|
"@types/node": {
|
||||||
"version": "16.11.68",
|
"version": "16.11.68",
|
||||||
"resolved": "https://registry.npmjs.org/@types/node/-/node-16.11.68.tgz",
|
"resolved": "https://registry.npmjs.org/@types/node/-/node-16.11.68.tgz",
|
||||||
|
|||||||
@@ -49,7 +49,8 @@
|
|||||||
"reflect-metadata": "^0.1.13",
|
"reflect-metadata": "^0.1.13",
|
||||||
"rimraf": "^3.0.2",
|
"rimraf": "^3.0.2",
|
||||||
"rxjs": "^7.2.0",
|
"rxjs": "^7.2.0",
|
||||||
"typeorm": "^0.3.10"
|
"typeorm": "^0.3.10",
|
||||||
|
"uuid": "^9.0.0"
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"@nestjs/cli": "^9.0.0",
|
"@nestjs/cli": "^9.0.0",
|
||||||
@@ -57,6 +58,7 @@
|
|||||||
"@nestjs/testing": "^9.0.0",
|
"@nestjs/testing": "^9.0.0",
|
||||||
"@types/express": "^4.17.13",
|
"@types/express": "^4.17.13",
|
||||||
"@types/jest": "28.1.8",
|
"@types/jest": "28.1.8",
|
||||||
|
"@types/multer": "^1.4.7",
|
||||||
"@types/node": "^16.0.0",
|
"@types/node": "^16.0.0",
|
||||||
"@types/passport-jwt": "^3.0.7",
|
"@types/passport-jwt": "^3.0.7",
|
||||||
"@types/passport-local": "^1.0.34",
|
"@types/passport-local": "^1.0.34",
|
||||||
|
|||||||
@@ -46,6 +46,7 @@ export class AuthenticationController {
|
|||||||
@UseGuards(AuthenticateGuard)
|
@UseGuards(AuthenticateGuard)
|
||||||
logout(@Req() request, @Res() response, @Next() next) {
|
logout(@Req() request, @Res() response, @Next() next) {
|
||||||
this.userService.setIsTwoFactorAuthenticatedWhenLogout(request.user.id);
|
this.userService.setIsTwoFactorAuthenticatedWhenLogout(request.user.id);
|
||||||
|
this.userService.updateStatus(request.user.id, 'disconnected');
|
||||||
request.logout(function(err) {
|
request.logout(function(err) {
|
||||||
if (err) { return next(err); }
|
if (err) { return next(err); }
|
||||||
response.redirect('/');
|
response.redirect('/');
|
||||||
|
|||||||
@@ -24,7 +24,7 @@ export class AuthenticateGuard implements CanActivate {
|
|||||||
export class TwoFactorGuard implements CanActivate {
|
export class TwoFactorGuard implements CanActivate {
|
||||||
async canActivate(context: ExecutionContext): Promise<boolean> {
|
async canActivate(context: ExecutionContext): Promise<boolean> {
|
||||||
const request = context.switchToHttp().getRequest();
|
const request = context.switchToHttp().getRequest();
|
||||||
console.log("TwoFactorGuard : Is User authenticated : " + request.isAuthenticated() + " and has 2FA enabled : " + request.user.isEnabledTwoFactorAuth + " and has 2FA verified : " + request.user.isTwoFactorAuthenticated);
|
//console.log("TwoFactorGuard : Is User authenticated : " + request.isAuthenticated() + " and has 2FA enabled : " + request.user.isEnabledTwoFactorAuth + " and has 2FA verified : " + request.user.isTwoFactorAuthenticated);
|
||||||
return request.isAuthenticated() && (request.user.isEnabledTwoFactorAuth === false
|
return request.isAuthenticated() && (request.user.isEnabledTwoFactorAuth === false
|
||||||
|| request.user.isTwoFactorAuthenticated === true);
|
|| request.user.isTwoFactorAuthenticated === true);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -5,7 +5,7 @@ import { AuthenticationService } from "../authentication.service";
|
|||||||
import { CreateUsersDto } from "src/users/dto/create-users.dto";
|
import { CreateUsersDto } from "src/users/dto/create-users.dto";
|
||||||
|
|
||||||
@Injectable()
|
@Injectable()
|
||||||
export class FortyTwoStrategy extends PassportStrategy(Strategy, "42") {
|
export class FortyTwoStrategy extends PassportStrategy(Strategy, "42") {
|
||||||
constructor(private authenticationService: AuthenticationService) {
|
constructor(private authenticationService: AuthenticationService) {
|
||||||
super({
|
super({
|
||||||
clientID: process.env.FORTYTWO_CLIENT_ID,
|
clientID: process.env.FORTYTWO_CLIENT_ID,
|
||||||
@@ -18,7 +18,7 @@ export class FortyTwoStrategy extends PassportStrategy(Strategy, "42") {
|
|||||||
async validate(accessToken: string, refreshToken: string, profile: Profile, callbackURL: string) {
|
async validate(accessToken: string, refreshToken: string, profile: Profile, callbackURL: string) {
|
||||||
console.log("Validate inside strategy.ts");
|
console.log("Validate inside strategy.ts");
|
||||||
console.log(profile.id, profile.username, profile.phoneNumbers[0].value, profile.emails[0].value, profile.photos[0].value);
|
console.log(profile.id, profile.username, profile.phoneNumbers[0].value, profile.emails[0].value, profile.photos[0].value);
|
||||||
const userDTO: CreateUsersDto = { fortyTwoId: profile.id, username: profile.username, email: profile.emails[0].value, image_url: profile.photos[0].value, isEnabledTwoFactorAuth: false };
|
const userDTO: CreateUsersDto = { fortyTwoId: profile.id, username: profile.username, email: profile.emails[0].value, image_url: 'default.png', isEnabledTwoFactorAuth: false , status: "connected" };
|
||||||
const user = await this.authenticationService.validateUser(userDTO);
|
const user = await this.authenticationService.validateUser(userDTO);
|
||||||
if (!user)
|
if (!user)
|
||||||
throw new UnauthorizedException();
|
throw new UnauthorizedException();
|
||||||
|
|||||||
@@ -0,0 +1,15 @@
|
|||||||
|
import { randomUUID } from "crypto";
|
||||||
|
import { diskStorage } from "multer";
|
||||||
|
import path from "path";
|
||||||
|
|
||||||
|
export const storageForAvatar = {
|
||||||
|
storage: diskStorage({
|
||||||
|
destination: './uploads/avatars',
|
||||||
|
filename: (req, file, cb) => {
|
||||||
|
console.log(file);
|
||||||
|
const filename : string = file.originalname.split(' ').join('_') + randomUUID();
|
||||||
|
const extension : string = path.extname(file.originalname);
|
||||||
|
cb(null, `${filename}${extension}`);
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
Binary file not shown.
|
After Width: | Height: | Size: 1.2 KiB |
@@ -9,6 +9,8 @@ export class CreateUsersDto {
|
|||||||
readonly email: string;
|
readonly email: string;
|
||||||
@IsString()
|
@IsString()
|
||||||
readonly image_url: string;
|
readonly image_url: string;
|
||||||
|
@IsString()
|
||||||
|
readonly status: string;
|
||||||
@IsBoolean()
|
@IsBoolean()
|
||||||
readonly isEnabledTwoFactorAuth: boolean;
|
readonly isEnabledTwoFactorAuth: boolean;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -5,4 +5,4 @@
|
|||||||
import { OmitType, PartialType } from "@nestjs/mapped-types";
|
import { OmitType, PartialType } from "@nestjs/mapped-types";
|
||||||
import { CreateUsersDto } from "./create-users.dto";
|
import { CreateUsersDto } from "./create-users.dto";
|
||||||
|
|
||||||
export class UpdateUsersDto extends OmitType(CreateUsersDto, ['fortyTwoId', 'email'] as const){}
|
export class UpdateUsersDto extends OmitType(CreateUsersDto, ['fortyTwoId', 'email', 'image_url', 'status'] as const){}
|
||||||
|
|||||||
@@ -21,14 +21,14 @@ export class User {
|
|||||||
@IsEmail()
|
@IsEmail()
|
||||||
email: string;
|
email: string;
|
||||||
|
|
||||||
@Column({ nullable: true })
|
@Column()
|
||||||
image_url : string;
|
image_url : string;
|
||||||
|
|
||||||
@Column({ nullable: true })
|
@Column({ nullable: true })
|
||||||
phone: string;
|
phone: string;
|
||||||
|
|
||||||
@Column('json', { nullable: true })
|
@Column({ default: 'disconnected' })
|
||||||
status: [string];
|
status: string;
|
||||||
|
|
||||||
// @Column()
|
// @Column()
|
||||||
// isFirstConnection: boolean;
|
// isFirstConnection: boolean;
|
||||||
|
|||||||
@@ -1,15 +1,29 @@
|
|||||||
import {
|
import {
|
||||||
Body, Controller, Delete, Get, HttpCode,
|
Body, Controller, Delete, Get, HttpException, NotFoundException, Patch, Post, Query, Req, Res, UploadedFile, UseGuards, UseInterceptors
|
||||||
HttpStatus, Param, Patch, Post, Query, Req, UseGuards
|
|
||||||
} from '@nestjs/common';
|
} from '@nestjs/common';
|
||||||
|
import { FileInterceptor } from '@nestjs/platform-express';
|
||||||
import { AuthenticateGuard, TwoFactorGuard } from 'src/auth/42/guards/42guards';
|
import { AuthenticateGuard, TwoFactorGuard } from 'src/auth/42/guards/42guards';
|
||||||
import { PaginationQueryDto } from 'src/common/dto/pagination-query.dto';
|
import { PaginationQueryDto } from 'src/common/dto/pagination-query.dto';
|
||||||
import { ValidationPipe } from 'src/common/validation/validation.pipe';
|
import { ValidationPipe } from 'src/common/validation/validation.pipe';
|
||||||
import { CreateUsersDto } from './dto/create-users.dto';
|
|
||||||
import { UpdateUsersDto } from './dto/update-users.dto';
|
import { UpdateUsersDto } from './dto/update-users.dto';
|
||||||
|
|
||||||
import { UsersService } from './users.service';
|
import { UsersService } from './users.service';
|
||||||
|
import { User } from './entities/user.entity';
|
||||||
|
import { diskStorage } from 'multer';
|
||||||
|
import path from 'path';
|
||||||
|
import { randomUUID } from 'crypto';
|
||||||
|
import { of } from 'rxjs';
|
||||||
|
|
||||||
|
export const storageForAvatar = {
|
||||||
|
storage: diskStorage({
|
||||||
|
destination: './uploads/avatars',
|
||||||
|
filename: (req, file, cb) => {
|
||||||
|
const filename : string = file.originalname.split(' ').join('_') + randomUUID();
|
||||||
|
console.log("RES : " )
|
||||||
|
const extension : string = path.extname(file.originalname);
|
||||||
|
cb(null, `${filename}${extension}`);
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
@Controller('user')
|
@Controller('user')
|
||||||
export class UsersController {
|
export class UsersController {
|
||||||
@@ -61,4 +75,28 @@ export class UsersController {
|
|||||||
remove(@Req() req) {
|
remove(@Req() req) {
|
||||||
return this.usersService.remove(req.user.id);
|
return this.usersService.remove(req.user.id);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@UseGuards(AuthenticateGuard)
|
||||||
|
@UseGuards(TwoFactorGuard)
|
||||||
|
@Post('avatar')
|
||||||
|
@UseInterceptors(FileInterceptor('file', storageForAvatar))
|
||||||
|
uploadAvatar(@UploadedFile() file, @Req() request){
|
||||||
|
const user : User = request.user;
|
||||||
|
this.usersService.updateAvatar(user.id, file.filename);
|
||||||
|
}
|
||||||
|
|
||||||
|
@UseGuards(AuthenticateGuard)
|
||||||
|
@UseGuards(TwoFactorGuard)
|
||||||
|
@Get('avatar')
|
||||||
|
getAvatar(@Req() request, @Res() response) {
|
||||||
|
const promise = this.usersService.getAvatarUrl(request.user.id).then((url) =>
|
||||||
|
{
|
||||||
|
if (url)
|
||||||
|
return of(response.sendFile(process.cwd() + '/uploads/avatars/' + url));
|
||||||
|
else
|
||||||
|
throw new NotFoundException('Avatar not found');
|
||||||
|
});
|
||||||
|
return promise;
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
import { HttpCode, HttpException, HttpStatus, Injectable, NotFoundException, } from '@nestjs/common';
|
import { HttpCode, HttpException, HttpStatus, Injectable, NotFoundException, } from '@nestjs/common';
|
||||||
import { InjectRepository } from '@nestjs/typeorm';
|
import { InjectRepository } from '@nestjs/typeorm';
|
||||||
import { NotFoundError } from 'rxjs';
|
import { NotFoundError, of } from 'rxjs';
|
||||||
import { User } from './entities/user.entity';
|
import { User } from './entities/user.entity';
|
||||||
import { ConnectionOptionsReader, Repository } from 'typeorm';
|
import { ConnectionOptionsReader, Repository } from 'typeorm';
|
||||||
import { CreateUsersDto } from './dto/create-users.dto';
|
import { CreateUsersDto } from './dto/create-users.dto';
|
||||||
@@ -9,6 +9,7 @@ import { Friendship } from '../friendship/entities/friendship.entity';
|
|||||||
import { isNumberString } from 'class-validator';
|
import { isNumberString } from 'class-validator';
|
||||||
import { PaginationQueryDto } from 'src/common/dto/pagination-query.dto';
|
import { PaginationQueryDto } from 'src/common/dto/pagination-query.dto';
|
||||||
import { PartialUsersDto } from './dto/partial-users.dto';
|
import { PartialUsersDto } from './dto/partial-users.dto';
|
||||||
|
import { join } from 'path';
|
||||||
|
|
||||||
// On va devoir sûrement trouver un moyen plus simple pour passer l'id, sûrement via des pipes
|
// On va devoir sûrement trouver un moyen plus simple pour passer l'id, sûrement via des pipes
|
||||||
// ou des interceptors, mais pour l'instant on va faire comme ça.
|
// ou des interceptors, mais pour l'instant on va faire comme ça.
|
||||||
@@ -65,7 +66,7 @@ export class UsersService {
|
|||||||
}
|
}
|
||||||
|
|
||||||
async update(id: string, updateUserDto: UpdateUsersDto) {
|
async update(id: string, updateUserDto: UpdateUsersDto) {
|
||||||
console.log(`Update user ${id} with ${updateUserDto.image_url} + ${updateUserDto.isEnabledTwoFactorAuth}`);
|
console.log(`Update user ${id} with ${updateUserDto.isEnabledTwoFactorAuth}`);
|
||||||
const user = await this.userRepository.preload(
|
const user = await this.userRepository.preload(
|
||||||
{id: +id,
|
{id: +id,
|
||||||
...updateUserDto});
|
...updateUserDto});
|
||||||
@@ -92,4 +93,22 @@ export class UsersService {
|
|||||||
async setAuthenticatorSecret(id: number, secret: string) {
|
async setAuthenticatorSecret(id: number, secret: string) {
|
||||||
return this.userRepository.update(id, {secretTwoFactorAuth: secret});
|
return this.userRepository.update(id, {secretTwoFactorAuth: secret});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
async updateStatus(id: number, status: string) {
|
||||||
|
return this.userRepository.update(id, {status: status});
|
||||||
|
}
|
||||||
|
|
||||||
|
async updateAvatar(id: number, avatar: string) {
|
||||||
|
return this.userRepository.update(id, {image_url: avatar});
|
||||||
|
}
|
||||||
|
|
||||||
|
async getAvatarUrl(id: number) {
|
||||||
|
const user = await this.userRepository.findOneBy({id: id});
|
||||||
|
if (!user)
|
||||||
|
throw new HttpException(`The user could not be found.`,HttpStatus.NOT_FOUND);
|
||||||
|
if (!user.image_url)
|
||||||
|
throw new HttpException(`The user has no avatar.`,HttpStatus.NOT_FOUND);
|
||||||
|
console.log(user.image_url);
|
||||||
|
return user.image_url;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,3 +0,0 @@
|
|||||||
FROM nginx:alpine
|
|
||||||
|
|
||||||
COPY ./conf/default.conf /etc/nginx/conf.d/default.conf
|
|
||||||
@@ -1,9 +1,10 @@
|
|||||||
<script>
|
<script>
|
||||||
import { onMount } from "svelte";
|
import { onMount } from "svelte";
|
||||||
|
|
||||||
|
let avatarUser, postVar, newAvatar, fileinput;
|
||||||
let usernameSv = "";
|
let usernameSv = "";
|
||||||
let image_urlSv = "";
|
let image_urlSv = "";
|
||||||
|
let uploadAvatarSuccess = false;
|
||||||
let gAuth = false;
|
let gAuth = false;
|
||||||
let errors = {usernameSv, image_urlSv};
|
let errors = {usernameSv, image_urlSv};
|
||||||
onMount(async () => {
|
onMount(async () => {
|
||||||
@@ -11,10 +12,28 @@
|
|||||||
then(response => response.json()).
|
then(response => response.json()).
|
||||||
then(data => {
|
then(data => {
|
||||||
usernameSv = data.username;
|
usernameSv = data.username;
|
||||||
image_urlSv = data.image_url;
|
|
||||||
gAuth = data.isEnabledTwoFactorAuth;
|
gAuth = data.isEnabledTwoFactorAuth;
|
||||||
});
|
});
|
||||||
|
await fetch("http://transcendance:8080/api/v2/user/avatar", {method: "GET"}).
|
||||||
|
then(response => {return response.blob()}).
|
||||||
|
then(data => {
|
||||||
|
const url = URL.createObjectURL(data);
|
||||||
|
avatarUser = url;
|
||||||
});
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
$: uploadAvatar = async() => {
|
||||||
|
const data = new FormData();
|
||||||
|
data.append("file", newAvatar[0]);
|
||||||
|
console.log(data);
|
||||||
|
await fetch("http://transcendance:8080/api/v2/user/avatar",
|
||||||
|
{
|
||||||
|
method : 'POST',
|
||||||
|
body : data,
|
||||||
|
})
|
||||||
|
.then(uploadAvatarSuccess = true)
|
||||||
|
.catch(errors.image_urlSv = "Something went wrong." )
|
||||||
|
}
|
||||||
|
|
||||||
$: submit = async() => {
|
$: submit = async() => {
|
||||||
errors.usernameSv = "";
|
errors.usernameSv = "";
|
||||||
@@ -23,10 +42,6 @@
|
|||||||
errors.usernameSv = "Username is required";
|
errors.usernameSv = "Username is required";
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if (image_urlSv === undefined || image_urlSv.trim() === "") {
|
|
||||||
errors.image_urlSv = "image_url is required";
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
console.log(usernameSv);
|
console.log(usernameSv);
|
||||||
await fetch("http://transcendance:8080/api/v2/user/",
|
await fetch("http://transcendance:8080/api/v2/user/",
|
||||||
{
|
{
|
||||||
@@ -36,46 +51,59 @@
|
|||||||
},
|
},
|
||||||
body: JSON.stringify({
|
body: JSON.stringify({
|
||||||
"username" : usernameSv,
|
"username" : usernameSv,
|
||||||
"image_url" : image_urlSv,
|
|
||||||
"isEnabledTwoFactorAuth" : gAuth
|
"isEnabledTwoFactorAuth" : gAuth
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
};
|
}
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<body>
|
<body>
|
||||||
<main class="form-signin w-100 m-auto">
|
<main class="form-signin w-100 m-auto">
|
||||||
<div class="p-20">
|
<div class="p-20">
|
||||||
|
{#if errors.image_urlSv}
|
||||||
|
<div class="alert alert-danger" role="alert">
|
||||||
|
{errors.image_urlSv}
|
||||||
|
</div>
|
||||||
|
{/if}
|
||||||
{#if errors.username}
|
{#if errors.username}
|
||||||
<div class="alert alert-danger" role="alert">
|
<div class="alert alert-danger" role="alert">
|
||||||
{errors.username}
|
{errors.username}
|
||||||
</div>
|
</div>
|
||||||
{/if}
|
{/if}
|
||||||
{#if errors.image_url}
|
{#if uploadAvatarSuccess}
|
||||||
<div class="alert alert-danger" role="alert">
|
<div class="alert alert-danger" role="alert">
|
||||||
{errors.image_url}
|
You avatar has been successfully uploaded !
|
||||||
</div>
|
</div>
|
||||||
{/if}
|
{/if}
|
||||||
|
<form on:submit|preventDefault={uploadAvatar}>
|
||||||
|
{#if avatarUser}
|
||||||
|
<img class="avatar" src={avatarUser} alt="" />
|
||||||
|
{/if}
|
||||||
|
<input
|
||||||
|
type="text"
|
||||||
|
bind:value={postVar}
|
||||||
|
placeholder={"choose your file"}
|
||||||
|
/>
|
||||||
|
<br />
|
||||||
|
<input
|
||||||
|
type="file"
|
||||||
|
bind:files={newAvatar} />
|
||||||
|
<br />
|
||||||
|
<button type="submit" class="p-2 bg-blue-500 text-white mt-4 px-6">
|
||||||
|
Choose avatar
|
||||||
|
</button>
|
||||||
|
</form>
|
||||||
<form on:submit|preventDefault={submit}>
|
<form on:submit|preventDefault={submit}>
|
||||||
<label for="username" class="block text-sm text-gray-600">Username</label>
|
<label for="username" class="block text-sm text-gray-600">Username</label>
|
||||||
<input id="username" type="text" placeholder=${usernameSv} class="block px-1 py-2 mt-2 border-2 border-gray-100 text-gray-800" bind:value={usernameSv} />
|
<input id="username" type="text" placeholder=${usernameSv} class="block px-1 py-2 mt-2 border-2 border-gray-100 text-gray-800" bind:value={usernameSv} />
|
||||||
|
|
||||||
<label for="image_url" class="block text-sm text-gray-600 mt-4">image_url</label>
|
|
||||||
<input id="image_url" type="image_url" bind:value={image_urlSv} placeholder=${image_urlSv} class="block px-1 py-2 mt-2 border-2 border-gray-100 text-gray-800" />
|
|
||||||
|
|
||||||
<div>
|
<div>
|
||||||
<input type="checkbox" bind:checked={gAuth} id="gAuth" name="gAuth">
|
<input type="checkbox" bind:checked={gAuth} id="gAuth" name="gAuth">
|
||||||
<label for="gAuth">Enable google authenticator</label>
|
<label for="gAuth">Enable google authenticator</label>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<button type="submit" class="p-2 bg-blue-500 text-white mt-4 px-6">
|
|
||||||
Change
|
|
||||||
</button>
|
|
||||||
</form>
|
</form>
|
||||||
</div>
|
</div>
|
||||||
</main>
|
</main>
|
||||||
</body>
|
</body>
|
||||||
|
|
||||||
<style>
|
<style>
|
||||||
|
|
||||||
body {
|
body {
|
||||||
|
|||||||
Reference in New Issue
Block a user