npm package: @occupop/lib-auth
Description: ...
Latest version: 1.0.3

# Package @occupop/lib-auth

This package is intended to be used with `@occupop/lib-container`
providing context function for GraphQL (or Express middleware) where AuthUser (or ScopedUser)
gets validated and signed to container.

This implementation refers to
https://www.apollographql.com/docs/apollo-server/data/context!

### *NPM registry token required!*

## Install
```bash
# Yarn
yarn add @occupop/lib-auth

# NPM
npm install @occupop/lib-auth

# Bun
bun add @occupop/lib-auth
```

## Env Setup
ENV variables required
```dotenv
JWT_SECRET=randomTokenProvidedByAuthService
```

## Register

```typescript
import {
    makeAuthContextValueFunction, makeAuthContextMiddleware
} from '@occupop/lib-auth'
//... all other imports omited... 

export const container = createTypedContainer({
    container: { asFunction: () => container, singleton: true },
    // ...
    // for graphql:
    authContextValueFunction: { asFunction: makeAuthContextValueFunction, singleton: true },
    // for express:
    authContextMiddleware: { asFunction: makeAuthContextMiddleware, singleton: true },
    // ...
})

```
**Note:** container need to be self registered/referenced to be possible to context function/middleware register
AuthUser and ScopedUser, that is extracted from request headers.

## Usage (with graphql)

```typescript
// server.ts
import { container } from '.container'

const { mongoClient, graphqlServer, graphqlStandalone, authContextValueFunction } = container.cradle

await mongoClient.connect()
console.log('Mongo connected')

const httpPort = process.env.API_PORT || 4000
await await graphqlStandalone(graphqlServer, {
  context: authContextValueFunction,
  listen: { port: httpPort },
})
console.log(`Server listening on http://localhost:${httpPort}`)
```

```typescript
// app/resolvers.ts
import { container } from '.container'

export const resolvers: GraphQLResolverMap<{ container: typeof container}> = {
  Query: {
    jobs: (source, { skip, take }, { container }, info) => {
      const { getJobsUseCase } = container.cradle
      return getJobsUseCase(skip, take)
    },
  },
}
```

```typescript
// app/use-cases/get-jobs-use-case.ts
import { type Deps } from '.container'

export function makeGetJobsUseCase({ authUser, jobService }: Deps) {
  return (skip = 0, take = 15) => {
    if (!authUser?.hiringCompanyUuid) throw 'not logged'
    if (take > 100) take = 100
    return jobService.getJobs(authUser.hiringCompanyUuid, skip, take)
  }
}
```




## Usage (with express)

```typescript
// server.ts
import { container } from '.container'

const { mongoClient, httpServer, appRouter, authContextMiddleware } = container.cradle

await mongoClient.connect()
console.log('Mongo connected')

const httpPort = process.env.API_PORT || 4000
httpServer.use(authContextMiddleware)
httpServer.use(appRouter)
await httpServer.listen(httpPort, () => {
    console.log(`Http listening on http://localhost:${httpPort}`)
})
// ...
```

```typescript
// app/router.ts
export function makeAppRouter({ httpRouter }: Deps) {
    return httpRouter
        //...
        .get('/jobs', (req, res) => {
            const { getJobsUseCase } = req.container.cradle
            res.json(getJobsUseCase(req.query.skip, req.query.take))
        })
        //...
}
```

```typescript
// app/use-cases/get-jobs-use-case.ts
import { type Deps } from '.container'

export function makeGetJobsUseCase({ authUser, jobService }: Deps) {
    return (skip = 0, take = 15) => {
        if (!authUser?.hiringCompanyUuid) throw 'not logged'
        if (take > 100) take = 100
        return jobService.getJobs(authUser.hiringCompanyUuid, skip, take)
    }
}
```