• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

teableio / teable / 11007013114

24 Sep 2024 04:29AM UTC coverage: 84.938% (-0.02%) from 84.954%
11007013114

Pull #935

github

web-flow
Merge 3ba8d67c8 into 10c0ccaac
Pull Request #935: feat: cross base link

5657 of 5961 branches covered (94.9%)

96 of 115 new or added lines in 7 files covered. (83.48%)

20 existing lines in 1 file now uncovered.

36975 of 43532 relevant lines covered (84.94%)

1164.23 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

86.54
/apps/nestjs-backend/src/features/share/share-auth.service.ts
1
import {
4✔
2
  BadRequestException,
4✔
3
  Injectable,
4✔
4
  UnauthorizedException,
4✔
5
  NotFoundException,
4✔
6
} from '@nestjs/common';
4✔
7
import { JwtService } from '@nestjs/jwt';
4✔
8
import { FieldType } from '@teable/core';
4✔
9
import type { IViewVo, IShareViewMeta } from '@teable/core';
4✔
10
import { PrismaService } from '@teable/db-main-prisma';
4✔
11
import { PermissionService } from '../auth/permission.service';
4✔
12
import { createFieldInstanceByRaw } from '../field/model/factory';
4✔
13
import { createViewVoByRaw } from '../view/model/factory';
4✔
14

4✔
15
export interface IShareViewInfo {
4✔
16
  shareId: string;
4✔
17
  tableId: string;
4✔
18
  view?: IViewVo;
4✔
19
}
4✔
20

4✔
21
export interface IJwtShareInfo {
4✔
22
  shareId: string;
4✔
23
  password: string;
4✔
24
}
4✔
25

4✔
26
@Injectable()
4✔
27
export class ShareAuthService {
4✔
28
  constructor(
179✔
29
    private readonly permissionService: PermissionService,
179✔
30
    private readonly prismaService: PrismaService,
179✔
31
    private readonly jwtService: JwtService
179✔
32
  ) {}
179✔
33

179✔
34
  async validateJwtToken(token: string) {
179✔
35
    try {
×
36
      return await this.jwtService.verifyAsync<IJwtShareInfo>(token);
×
37
    } catch {
×
38
      throw new UnauthorizedException();
×
39
    }
×
40
  }
×
41

179✔
42
  async authShareView(shareId: string, pass: string): Promise<string | null> {
179✔
43
    const view = await this.prismaService.view.findFirst({
4✔
44
      where: { shareId, enableShare: true, deletedTime: null },
4✔
45
      select: { shareId: true, shareMeta: true },
4✔
46
    });
4✔
47
    if (!view) {
4✔
48
      return null;
×
49
    }
×
50
    const shareMeta = view.shareMeta ? (JSON.parse(view.shareMeta) as IShareViewMeta) : undefined;
4✔
51
    const password = shareMeta?.password;
4✔
52
    if (!password) {
4✔
53
      throw new BadRequestException('Password restriction is not enabled');
×
54
    }
×
55
    return pass === password ? shareId : null;
4✔
56
  }
4✔
57

179✔
58
  async authToken(jwtShareInfo: IJwtShareInfo) {
179✔
59
    return await this.jwtService.signAsync(jwtShareInfo);
2✔
60
  }
2✔
61

179✔
62
  async getShareViewInfo(shareId: string): Promise<IShareViewInfo> {
179✔
63
    const view = await this.prismaService.view.findFirst({
42✔
64
      where: { shareId, enableShare: true, deletedTime: null },
42✔
65
    });
42✔
66
    if (!view) {
42✔
67
      throw new BadRequestException('share view not found');
2✔
68
    }
2✔
69

40✔
70
    return {
40✔
71
      shareId,
40✔
72
      tableId: view.tableId,
40✔
73
      view: createViewVoByRaw(view),
40✔
74
    };
40✔
75
  }
40✔
76

179✔
77
  async getLinkViewInfo(linkFieldId: string): Promise<IShareViewInfo> {
179✔
78
    const fieldRaw = await this.prismaService.field
4✔
79
      .findFirstOrThrow({
4✔
80
        where: { id: linkFieldId, deletedTime: null },
4✔
81
      })
4✔
82
      .catch((_err) => {
4✔
NEW
83
        throw new NotFoundException(`Field ${linkFieldId} not exist`);
×
NEW
84
      });
×
85

4✔
86
    const field = createFieldInstanceByRaw(fieldRaw);
4✔
87

4✔
88
    if (field.type !== FieldType.Link) {
4✔
NEW
89
      throw new BadRequestException('field is not a link field');
×
NEW
90
    }
×
91

4✔
92
    // make sure user has permission to access the table where the link field from
4✔
93
    await this.permissionService.validPermissions(fieldRaw.tableId, [
4✔
94
      'table|read',
4✔
95
      'record|read',
4✔
96
      'field|read',
4✔
97
    ]);
4✔
98

2✔
99
    return {
2✔
100
      shareId: linkFieldId,
2✔
101
      tableId: field.options.foreignTableId,
2✔
102
    };
2✔
103
  }
2✔
104
}
179✔
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2025 Coveralls, Inc