8000 feat: Feathers v5 core refactoring and features by daffl · Pull Request #2255 · feathersjs/feathers · GitHub
[go: up one dir, main page]

Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
8000 Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion .codeclimate.yml
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ checks:
threshold: 300
method-complexity:
config:
threshold: 6
threshold: 8
method-count:
config:
threshold: 20
Expand Down
1 change: 1 addition & 0 deletions .mocharc.json
Original file line number Diff line number Diff line change
Expand Up @@ -2,5 +2,6 @@
"timeout": 20000,
"require": [ "ts-node/register", "source-map-support/register" ],
"reporter": "Dot",
"extension": ".test.ts",
"exit": true
}
3 changes: 2 additions & 1 deletion packages/adapter-commons/src/service.ts
Original file line number Diff line number Diff line change
Expand Up @@ -173,7 +173,6 @@ export class AdapterService<T = any> implements ServiceMethods<T|Paginated<T>> {

create (data: Partial<T>, params?: Params): Promise<T>;
create (data: Partial<T>[], params?: Params): Promise<T[]>;
create (data: Partial<T> | Partial<T>[], params?: Params): Promise<T | T[]>;
create (data: Partial<T> | Partial<T>[], params?: Params): Promise<T | T[]> {
if (Array.isArray(data) && !this.allowsMulti('create')) {
return Promise.reject(new MethodNotAllowed('Can not create multiple entries'));
Expand Down Expand Up @@ -213,4 +212,6 @@ export class AdapterService<T = any> implements ServiceMethods<T|Paginated<T>> {

return callMethod(this, '_remove', id, params);
}

async setup () {}
}
4 changes: 2 additions & 2 deletions packages/adapter-memory/test/index.test.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import assert from 'assert';
import adapterTests from '@feathersjs/adapter-tests';
import errors from '@feathersjs/errors';
import feathers from '@feathersjs/feathers';
import { feathers } from '@feathersjs/feathers';

import { memory } from '../src';

Expand Down Expand Up @@ -85,7 +85,7 @@ describe('Feathers Memory Service', () => {
age: 33
});

const updatedPerson = await people.update(person.id.toString(), person);
const updatedPerson: any = await people.update(person.id.toString(), person);

assert.strictEqual(typeof updatedPerson.id, 'number');

Expand Down
3D1D 2 changes: 1 addition & 1 deletion packages/authentication-client/src/core.ts
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,7 @@ export class AuthenticationClient {
options: AuthenticationClientOptions;

constructor (app: Application, options: AuthenticationClientOptions) {
const socket = app.io || (app as any).primus;
const socket = app.io;
const storage = new StorageWrapper(app.get('storage') || options.storage);

this.app = app;
Expand Down
2 changes: 1 addition & 1 deletion packages/authentication-client/test/index.test.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import assert from 'assert';
import feathers, { Application } from '@feathersjs/feathers';
import { feathers, Application } from '@feathersjs/feathers';

import client from '../src';
import { AuthenticationClient } from '../src';
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import axios from 'axios';
import feathers, { Application as FeathersApplication } from '@feathersjs/feathers';
import { Server } from 'http';
import { feathers, Application as FeathersApplication } from '@feathersjs/feathers';
import * as express from '@feathersjs/express';
import rest from '@feathersjs/rest-client';

Expand All @@ -9,17 +10,17 @@ import commonTests from './commons';

describe('@feathersjs/authentication-client Express integration', () => {
let app: express.Application;
let server: any;
let server: Server;

before(() => {
before(async () => {
const restApp = express.default(feathers())
.use(express.json())
.configure(express.rest())
.use(express.parseAuthentication());
app = getApp(restApp as unknown as FeathersApplication) as express.Application;
app.use(express.errorHandler());

server = app.listen(9776);
server = await app.listen(9776);
});

after(done => server.close(() => do AD9F ne()));
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import { io } from 'socket.io-client';
import assert from 'assert';
import feathers, { Application } from '@feathersjs/feathers';
import { feathers, Application } from '@feathersjs/feathers';
import socketio from '@feathersjs/socketio';
import socketioClient from '@feathersjs/socketio-client';

Expand All @@ -11,10 +11,10 @@ import commonTests from './commons';
describe('@feathersjs/authentication-client Socket.io integration', () => {
let app: Application;

before(() => {
before(async () => {
app = getApp(feathers().configure(socketio()));

app.listen(9777);
await app.listen(9777);
});

after(done => app.io.close(() => done()));
Expand Down
2 changes: 1 addition & 1 deletion packages/authentication-local/src/hooks/hash-password.ts
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ export default function hashPassword (field: string, options: HashPasswordOption
throw new Error('The hashPassword hook requires a field name option');
}

return async (context: HookContext) => {
return async (context: HookContext<any, any>) => {
if (context.type !== 'before') {
throw new Error('The \'hashPassword\' hook should only be used as a \'before\' hook');
}
Expand Down
2 changes: 1 addition & 1 deletion packages/authentication-local/src/hooks/protect.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import omit from 'lodash/omit';
import { HookContext } from '@feathersjs/feathers';

export default (...fields: string[]) => (context: HookContext) => {
export default (...fields: string[]) => (context: HookContext<any, any>) => {
const result = context.dispatch || context.result;
const o = (current: any) => {
if (typeof current === 'object' && !Array.isArray(current)) {
Expand Down
2 changes: 1 addition & 1 deletion packages/authentication-local/src/strategy.ts
Original file line number Diff line number Diff line change
Expand Up @@ -76,7 +76,7 @@ export class LocalStrategy extends AuthenticationBaseStrategy {

async getEntity (result: any, params: Params) {
const entityService = this.entityService;
const { entityId = entityService.id, entity } = this.configuration;
const { entityId = (entityService as any).id, entity } = this.configuration;

if (!entityId || result[entityId] === undefined) {
throw new NotAuthenticated('Could not get local entity');
Expand Down
Original file line number Diff line number Diff line change
@@ -1,11 +1,16 @@
const feathers = require('@feathersjs/feathers');
const { memory } = require('@feathersjs/adapter-memory');
const { AuthenticationService, JWTStrategy } = require('@feathersjs/authentication');
import { feathers } from '@feathersjs/feathers';
import { memory, Service as MemoryService } from '@feathersjs/adapter-memory';
import { AuthenticationService, JWTStrategy } from '@feathersjs/authentication';

const { LocalStrategy, hooks } = require('../src');
import { LocalStrategy, hooks } from '../src';
const { hashPassword, protect } = hooks;

module.exports = (app = feathers()) => {
export type ServiceTypes = {
authentication: AuthenticationService;
users: MemoryService;
}

export function createApplication (app = feathers<ServiceTypes>()) {
const authentication = new AuthenticationService(app);

app.set('authentication', {
Expand All @@ -23,8 +28,8 @@ module.exports = (app = feathers()) => {
authentication.register('jwt', new JWTStrategy());
authentication.register('local', new LocalStrategy());

app.use('/authentication', authentication);
app.use('/users', memory({
app.use('authentication', authentication);
app.use('users', memory({
multi: [ 'create' ],
paginate: {
default: 10,
Expand All @@ -34,10 +39,10 @@ module.exports = (app = feathers()) => {

app.service('users').hooks({
before: {
create: hashPassword('password')
create: [ hashPassword('password') ]
},
after: {
all: protect('password'),
all: [ protect('password') ],
get: [context => {
if (context.params.provider) {
context.result.fromGet = true;
Expand All @@ -49,4 +54,4 @@ module.exports = (app = feathers()) => {
});

return app;
};
}
Original file line number Diff line number Diff line change
Expand Up @@ -2,13 +2,12 @@ import assert from 'assert';
import { Application } from '@feathersjs/feathers';

import { hooks } from '../../src';
// @ts-ignore
import createApplication from '../fixture';
import { createApplication, ServiceTypes } from '../fixture';

const { hashPassword } = hooks;

describe('@feathersjs/authentication-local/hooks/hash-password', () => {
let app: Application;
let app: Application<ServiceTypes>;

beforeEach(() => {
app = createApplication();
Expand Down
29 changes: 13 additions & 16 deletions packages/authentication-local/test/strategy.test.ts
Original file line number Diff line number Diff line change
@@ -1,15 +1,15 @@
import assert from 'assert';
import omit from 'lodash/omit';
import { LocalStrategy } from '../src';
// @ts-ignore
import createApplication from './fixture';
import { Application } from '@feathersjs/feathers';

import { LocalStrategy } from '../src';
import { createApplication, ServiceTypes } from './fixture';

describe('@feathersjs/authentication-local/strategy', () => {
const password = 'localsecret';
const email = 'localtester@feathersjs.com';

let app: Application;
let app: Application<ServiceTypes>;
let user: any;

beforeEach(async () => {
Expand Down Expand Up @@ -47,7 +47,7 @@ describe('@feathersjs/authentication-local/strategy', () => {
});

it('getEntity', async () => {
const [ strategy ] = app.service('authentication').getStrategies('local');
const [ strategy ] = app.service('authentication').getStrategies('local') as [ LocalStrategy ];
let entity = await strategy.getEntity(user, {});

assert.deepStrictEqual(entity, user);
Expand All @@ -72,17 +72,14 @@ describe('@feathersjs/authentication-local/strategy', () => {
it('strategy fails when strategy is different', async () => {
const [ local ] = app.service('authentication').getStrategies('local');

try {
await local.authenticate({
strategy: 'not-me',
password: 'dummy',
email
});
assert.fail('Should never get here');
} catch (error) {
assert.strictEqual(error.name, 'NotAuthenticated');
assert.strictEqual(error.message, 'Invalid login');
}
await assert.rejects(() => local.authenticate({
strategy: 'not-me',
password: 'dummy',
email
}, {}), {
name: 'NotAuthenticated',
message: 'Invalid login'
});
});

it('fails when password is wrong', async () => {
Expand Down
4 changes: 2 additions & 2 deletions packages/authentication-oauth/src/strategy.ts
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@ export class OAuthStrategy extends AuthenticationBaseStrategy {
get entityId (): string {
const { entityService } = this;

return this.configuration.entityId || (entityService && entityService.id);
return this.configuration.entityId || (entityService && (entityService as any).id);
}

async getEntityQuery (profile: OAuthProfile, _params: Params) {
Expand Down Expand Up @@ -123,7 +123,7 @@ export class OAuthStrategy extends AuthenticationBaseStrategy {

async getEntity (result: any, params: Params) {
const { entityService } = this;
const { entityId = entityService.id, entity } = this.configuration;
const { entityId = (entityService as any).id, entity } = this.configuration;

if (!entityId || result[entityId] === undefined) {
throw new NotAuthenticated('Could not get oAuth entity');
Expand Down
4 changes: 1 addition & 3 deletions packages/authentication-oauth/test/express.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,9 +7,7 @@ describe('@feathersjs/authentication-oauth/express', () => {
let server: Server;

before(async () => {
server = app.listen(9876);

await new Promise<void>(resolve => server.once('listening', () => resolve()));
server = await app.listen(9876);
});

after(() => server.close());
Expand Down
2 changes: 1 addition & 1 deletion packages/authentication-oauth/test/fixture.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import feathers, { Params } from '@feathersjs/feathers';
import { feathers, Params } from '@feathersjs/feathers';
import express, { rest, errorHandler } from '@feathersjs/express';
import { memory } from '@feathersjs/adapter-memory';
import { AuthenticationService, JWTStrategy, AuthenticationRequest } from '@feathersjs/authentication';
Expand Down
2 changes: 1 addition & 1 deletion packages/authentication-oauth/test/index.test.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import { strict as assert } from 'assert';
import feathers from '@feathersjs/feathers';
import { feathers } from '@feathersjs/feathers';
import { setup, express, OauthSetupSettings } from '../src';
import { AuthenticationService } from '@feathersjs/authentication';

Expand Down
2 changes: 1 addition & 1 deletion packages/authentication-oauth/test/strategy.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ import { app, TestOAuthStrategy } from './fixture';
import { AuthenticationService } from '@feathersjs/authentication';

describe('@feathersjs/authentication-oauth/strategy', () => {
const authService: AuthenticationService = app.service('authentication');
const authService = app.service('authentication') as unknown as AuthenticationService;
const [ strategy ] = authService.getStrategies('test') as TestOAuthStrategy[];

it('initializes, has .entityId and configuration', () => {
Expand Down
2 changes: 1 addition & 1 deletion packages/authentication/src/hooks/authenticate.ts
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ export default (originalSettings: string | AuthenticateHookSettings, ...original
throw new Error('The authenticate hook needs at least one allowed strategy');
}

return async (context: HookContext) => {
return async (context: HookContext<any, any>) => {
const { app, params, type, path, service } = context;
const { strategies } = settings;
const { provider, authentication } = params;
Expand Down
19 changes: 9 additions & 10 deletions packages/authentication/src/service.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,21 +4,20 @@ import { NotAuthenticated } from '@feathersjs/errors';
import { AuthenticationBase, AuthenticationResult, AuthenticationRequest } from './core';
import { connection, event } from './hooks';
import '@feathersjs/transport-commons';
import { Application, Params, ServiceMethods, ServiceAddons } from '@feathersjs/feathers';
import { Params, ServiceMethods, ServiceAddons } from '@feathersjs/feathers';
import jsonwebtoken from 'jsonwebtoken';

const debug = Debug('@feathersjs/authentication/service');

declare module '@feathersjs/feathers/lib/declarations' {
interface Application<ServiceTypes = {}> { // eslint-disable-line

interface FeathersApplication<ServiceTypes = {}, AppSettings = {}> { // eslint-disable-line
/**
* Returns the default authentication service or the
* authentication service for a given path.
*
* @param location The service path to use (optional)
*/
defaultAuthentication (location?: string): AuthenticationService;
defaultAuthentication? (location?: string): AuthenticationService;
}

interface Params {
Expand All @@ -28,10 +27,10 @@ declare module '@feathersjs/feathers/lib/declarations' {
}

// eslint-disable-next-line
export interface AuthenticationService extends ServiceAddons<AuthenticationResult> {}
export interface AuthenticationService extends ServiceAddons<AuthenticationResult, AuthenticationResult> {}

export class AuthenticationService extends AuthenticationBase implements Partial<ServiceMethods<AuthenticationResult>> {
constructor (app: Application, configKey = 'authentication', options = {}) {
constructor (app: any, configKey = 'authentication', options = {}) {
super(app, configKey, options);

if (typeof app.defaultAuthentication !== 'function') {
Expand Down Expand Up @@ -93,7 +92,7 @@ export class AuthenticationService extends AuthenticationBase implements Partial
* @param data The authentication request (should include `strategy` key)
* @param params Service call parameters
*/
async create (data: AuthenticationRequest, params: Params) {
async create (data: AuthenticationRequest, params?: Params) {
const authStrategies = params.authStrategies || this.configuration.authStrategies;

if (!authStrategies.length) {
Expand Down Expand Up @@ -132,7 +131,7 @@ export class AuthenticationService extends AuthenticationBase implements Partial
* @param id The JWT to remove or null
* @param params Service call parameters
*/
async remove (id: string | null, params: Params) {
async remove (id: string | null, params?: Params) {
const { authentication } = params;
const { authStrategies } = this.configuration;

Expand All @@ -149,7 +148,7 @@ export class AuthenticationService extends AuthenticationBase implements Partial
/**
* Validates the service configuration.
*/
setup () {
async setup () {
// The setup method checks for valid settings and registers the
// connection and event (login, logout) hooks
const { secret, service, entity, entityId } = this.configuration;
Expand All @@ -172,7 +171,7 @@ export class AuthenticationService extends AuthenticationBase implements Partial
}
}

this.hooks({
(this as any).hooks({
after: {
create: [ connection('login'), event('login') ],
remove: [ connection('logout'), event('logout') ]
Expand Down
Loading
0